大话重构7:重构是一系列的等量变换

大话重构7:重构是一系列的等量变换

大家好,又见面了,我是全栈君。

毫无疑问,系统重构是一件如履薄冰、如坐针毡、你必须时时小心应对的工作,你就像走在钢丝上的人,每一步你都必需要保证正确,一个不经意的失误就可能让你万劫不复。

虽然如此,仅仅要你掌握了正确的方法。即使站在钢丝上也能如履平地,而这个正确的方法。就是那些被证明是正确的重构方法。

说了那么多。你一定開始好奇,系统重构究竟都是一些什么方法呢?行了,我也就不卖关子了,我们来看看重构方法工具箱里都有些什么东东。

系统重构要求我们对代码的每一步改动。都不能改变软件的外部行为,因此在系统重构中的全部方法。都是一种代码的等量变换。重构的过程,就好像在做数学题,一步一步地进行算式的等量变换。经过一系列等量变换,终于的结果尽管在形式上与原式不一样。但通过计算能够得到与原式全然同样的结果。

这样的等量变换对于重构来说很重要,它使得我们进行重构以后,程序还是那些程序,代码还是那些代码。可是,等量变换不等于原地踏步。正如矩阵通过等量变换能够得到方程组的解。微积分能够通过等量变换计算终于的结果,重构通过等量变换,在保证代码正确的同一时候,能够使程序结构得到优化。

为了说明系统重构中的这样的等量变换。我们来看看一个简单的样例。原始程序是这样的:

 

public class HelloWorld {
	public String sayHello(Date now, String user){
		Calendar c;
		int h;
		String s = null;
		c = Calendar.getInstance();
		c.setTime(now);
		h = c.get(Calendar.HOUR_OF_DAY);
		if(h>=6 && h<12){
			s = "Good morning!";
		}else if(h>=12 && h<19){
			s = "Good afternoon!";
		}else{
			s = "Good night!";
		}
		s = "Hi, "+user+". "+s;
		return s;
	}
}

这是一个很easy的HelloWorld程序。写得简单是为了大家更easy看懂程序的变换过程。

这个程序尽管简单却符合遗留系统的很多特点:没有凝视、顺序编程、没有层次、聚合度低。等等。因此我们进行了初步重构,添加凝视、调整顺序、重命名变量、进行分段:

 

/**
 * The Refactoring's hello-world program
 * @author fangang
 */
public class HelloWorld {
	/**
	 * Say hello to everyone
	 * @param now
	 * @param user
	 * @return the words what to say
	 */
	public String sayHello(Date now, String user){
		//Get current hour of day
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(now);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		
		//Get the right words to say hello
		String words = null;
		if(hour>=6 && hour<12){
			words = "Good morning!";
		}else if(hour>=12 && hour<19){
			words = "Good afternoon!";
		}else{
			words = "Good night!";
		}
		words = "Hi, "+user+". "+words;
		return words;
	}
}

然后将两段凝视中的代码分别提取出来形成getHour()与getSecondGreeting()函数:

 

/**
 * The Refactoring's hello-world program
 * @author fangang
 */
public class HelloWorld {
	/**
	 * Say hello to everyone
	 * @param now
	 * @param user
	 * @return the words what to say
	 */
	public String sayHello(Date now, String user){
		int hour = getHour(now);
		return "Hi, "+user+". "+getSecondGreeting(hour);
	}
	
	/**
	 * Get current hour of day.
	 * @param now
	 * @return current hour of day
	 */
	private int getHour(Date now){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(now);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}
	
	/**
	 * Get the second greeting.
	 * @param hour
	 * @return the second greeting
	 */
	private String getSecondGreeting(int hour){
		if(hour>=6 && hour<12){
			return "Good morning!";
		}else if(hour>=12 && hour<19){
			return "Good afternoon!";
		}else{
			return "Good night!";
		}
	}
}

通过这个样例我们能够看到。将没有先后顺序的语句调整编写顺序是一种等量变换,将语句中某段相对独立的语句提取出来形成一个函数,而让原语句调用这个函数,也是一种等量变换。除此之外,调整函数名称、改动变量名称等等。都是等量变换。

等量变换,程序还是那些程序,运行的结果还是那些结果,但程序组织结构发生了变化。变得更加可读、可维护、易变更了,这就是重构的意义。

将密密麻麻的程序代码依照功能划分在数个函数中,能够有效地提高代码的可读性。将程序中各种各样的变量和函数合理地予以命名,并在函数头或定义处适时地进行凝视,也是在提高代码可读性;将各种各样品种繁多的函数恰当地分配到各自的对象中合理地组织起来,则是在有效提高系统的可维护性与易变更性。这些对于一个遗留系统的日常维护与生命延续都是很有帮助的。

大话重构连载首页:http://blog.csdn.net/mooodo/article/details/32083021

特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重。谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115731.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C++ GetUserName()

    C++ GetUserName()

    2022年3月12日
    41
  • 教你win10系统显卡驱动安装失败的解决方法【系统天地】

    教你win10系统显卡驱动安装失败的解决方法【系统天地】我们日常在对电脑的使用过程中,经常都会遇到这样或那样的问题。比如说win10系统显卡驱动安装失败该怎么办呢?别着急,还有小编在呢?接下来小编就来告诉大家win10电脑系统显卡驱动安装失败怎么解决。详细教你win10系统显卡驱动安装失败怎么办:方法一,删除之前的显卡驱动文件重新安装1,首先,右键点击“此电脑”,菜单栏选择“管理”。2,进入计算机管理界面后,点击“设备管理器”,然后在界面右侧展开“显示适配器”选项,并右键点击显卡驱动程序,菜单栏选择“属性”下一步。3,点击“卸载设备”。4,显卡驱动程

    2022年5月22日
    36
  • idea 在线激活码_在线激活

    (idea 在线激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html0VOERWDQ5R-eyJsaWNlbnNlSWQi…

    2022年3月31日
    88
  • 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)  作为一名前端工程师,必须搞懂JS中的prototype、__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__proto__属性的两边是各由两个下划线构成(这里为了方便大家看清,在两下划线之间加入了一个空格:__proto__)。  现在正式开始!让我们从如下一个简单的例…

    2022年7月23日
    12
  • 云计算仿真框架CloudSim介绍

    云计算仿真框架CloudSim介绍幻灯片1云计算仿真框架CloudSim介绍jiangzw#ihep.ac.cn(以下为本人某次报告做的调研的PPT及其它一些实践记录,为保证清晰度,一些插入的图片较大,可在新标签页中打开)(本文基于署名2.5中国大陆许可协议发布,欢迎转载、演绎,但是必须保留本文的署名John并包含本文链接。)欢迎交流2013年04月09日

    2022年10月13日
    2
  • ROS | 机器人操作系统简介

    ROS | 机器人操作系统简介机器人操作系统(ROS)简介1.ROS基本概念2.ROS架构2.1OS层2.2中间层2.3应用层3.通信机制4.计算图4.1节点(Node)4.2节点管理器(Master)4.3消息(Message)4.4话题(Topic)4.5服务(Service)4.6动作(Action)4.7消息记录包(Bag)4.8参数(Parameter)4.9功能包(Package)4.10功能包清单(Packagemanifest)4.11元功能包(MetaPackage)5.开源社区1.ROS基本概念ROSWik

    2025年8月22日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号