大话重构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

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


posted @ 2016-03-09 20:01  yxwkaifa  阅读(237)  评论(0编辑  收藏  举报