下面我们来盘点一下系统重构工具箱里都有什么,也就是看一看系统重构到底都有哪些方法。系统重构总是在不同层次上调整我们的代码,因此重构方法也就分为了多个层次。从总体上看,重构方法分为以下几个层次:方法的重构、对象的重构、对象间的重构、继承体系间的重构、组织数据的重构与体系架构的重构。
前面那个例子我们可以清楚地看到方法的重构过程。方法的重构往往发生在一个对象的内部,是对一个对象内部的优化。从这个例子中,我们首先看到了增加注释、调整顺序、重命名变量、进行分段等操作,这些虽然不是什么重构方法,却是我们进行前期准备的常用技法。随后我们将通过注释分段存放的各个代码段提取出来,形成单独的函数。这种重构方法被称为“抽取方法(Extract Method)”。
随后我们继续重构。仔细观察这个程序我们发现,这个程序内聚性不好。最好用一个DateUtil管理诸如getHour()的方法,用Greeting管理各种问候语及其规则,因此我们进行了如下重构:
/**
* A utility about time.
* @author fangang
*/
public class DateUtil {
/**
* Get hour of day.
* @param date
* @return hour of day
*/
public int getHour(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.HOUR_OF_DAY);
}
}
/**
* All kinds of greeting.
* @author fangang
*/
public class Greeting {
/**
* Get the first greeting.
* @param user
* @return Hi, {user}.
*/
public String getFirstGreeting(String user){
return "Hi, "+user+". ";
}
/**
* Get the second greeting.
* @param hour
* @return if in the morning, say "Good morning!",
* if in the afternoon, say "Good afternoon!",
* else say "Good night!".
*/
public 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!";
}
}
}
/**
* 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){
DateUtil dateUtil = new DateUtil();
int hour = dateUtil.getHour(now);
Greeting greeting = new Greeting();
return greeting.getFirstGreeting(user)+
greeting.getSecondGreeting(hour);
}
}
这里我们将getHour()从HelloWorld类中抽取出来,放到了DateUtil类中,使HelloWorld类中仅保留一个引用。同时,我们将getFirstGreeting()与getSecondGreeting()从HelloWorld类中抽取出来,放到了Greeting类中,使原程序变为引用。这样的技法我们称之为“抽取类(Extract Class)”。
再仔细观察这一段程序:
/**
* Get the second greeting.
* @param hour
* @return if in the morning, say "Good morning!",
* if in the afternoon, say "Good afternoon!",
* else say "Good night!".
*/
public 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!";
}
}
除了morning, afternoon, night以外,如果我们再增加evening,程序的可扩展性就不好了。因此我们将它们提取出GreetingRule接口,并分别编写了morning, afternoon, night和evening的实现类:
/**
* Greeting rules interface
* @author fangang
*/
public interface GreetingRule {
/**
* @param hour
* @return whether the rule is right
*/
public boolean isRight(int hour);
/**
* @return the greeting words
*/
public String getGreeting();
}
/**
* The greeting in the morning
* @author fangang
*/
public class MorningGreeting implements GreetingRule {
/* (non-Javadoc)
* @see org.refactoring.helloWorld...GreetingRule#getGreeting()
*/
@Override
public String getGreeting() {
return "Good morning! ";
}
/* (non-Javadoc)
* @see org.refactoring.helloWorld...GreetingRule#isRight(int)
*/
@Override
public boolean isRight(int hour) {
if(hour>=6 && hour<12){
return true;
}
return false;
}
}
其它几个实现类我就不累牍了,最后将getSecondGreeting()方法改成这样:
/**
* Get the second greeting.
* @param hour
* @return if in the morning, say "Good morning!",
* if in the afternoon, say "Good afternoon!",
* if in the evening, say "Good evening! ",
* else, say "Good night!".
*/
public String getSecondGreeting(int hour){
for(GreetingRule greetingRule : greetingRules){
if(greetingRule.isRight(hour)){
return greetingRule.getGreeting();
}
}
throw new RuntimeException("Error when greeting! ");
}
这种将相似的,或者同类型的代码抽取出来形成接口,以及接口下的多个实现,我们称之为“抽取接口(Extract Interface)”。
看了这些例子你可能会有一个疑问,这样简单的程序搞成这样,是否值得?是的,不错,程序的结构应当与需求的复杂度相适应。简单的需求编写简单的程序,复杂的需求编写复杂的程序。如果将简单的需求,为了玩技术,搞成了复杂的程序,那就是“过度设计”。但这里为了更加清楚的向大家展示重构,又能够使大家不要因为复杂的程序而分心,故而将简单程序过度设计了一把。但在后面我们可以看到,当业务需求逐渐复杂时,我们进行以上这些重构是值得的。
文后附录列出了所有的重构方法,它们都来源于重构经典书籍《重构,改善既有代码的设计》,在日后的时间我们应当反复咀嚼这些方法。
正如武侠大师金庸所说的“无招胜有招”,如此多的重构方法不是要让你去生搬硬套,而是应该对其进行深刻理解以后,最终变成你自己的重构方法。我们在实际工作中不要过于介意我们用了什么重构方法,哪次重构是用的哪个方法,只要是合适的设计就OK。但是,在无招胜有招之前,我们必须要有招,即学会了、理解了各个招式,在实际工作中你才能想起这些招式,去运用这些招式。学习与实践总是两个相辅相成、相互促进的过程。
然而,系统重构经典书籍不少,指导我们实践的书籍却不多。相信有许许多多有志之士,在看过重构的书籍以后,激情洋溢、热血澎湃,但回到现实世界中,回到实际工作中却无所适从,经过一番苦苦挣扎之后,从此作罢。因此,本书将从实践出发,用实际工作中的示例,用更加真实的视角向大家展示,系统重构是怎样指导我们工作的,让大家真正地用起来。
大话重构连载首页:
http://fangang.iteye.com/blog/2081995
特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢!
分享到:
相关推荐
Android之大话设计模式——:抽象工厂模式借鉴.pdf
大话Oracle RAC:集群、高可用性、备份与恢复(带目录清晰中文完整版)
大话Oracle RAC:集群、高可用性、备份与恢复。 此书被认为不可多得的好资料之一:大话Oracle RAC(PDF经典),看完之后深有感触,发出来共享一下。
Android之大话设计模式——:抽象工厂模式参考.pdf
《大话Oracle.RAC:集群、高可用性、备份与恢复(第2版)》是一部深入探讨Oracle数据库Real Application Clusters(RAC)技术的专业书籍,主要围绕Oracle RAC的集群架构、高可用性策略以及数据库的备份与恢复策略...
初中语文文摘历史“大话王”郭台铭:被夏普狠狠摔了个大跟
《大话移动APP测试》是一本详尽介绍Android与iOS平台测试应用的指南,旨在帮助读者深入理解并掌握移动应用的测试技术。本书全面覆盖了移动端的测试领域,包括平台特性、设备兼容性、功能测试、性能测试、安全测试等...
《大话存储:存储系统底层架构原理极限剖析(终极版)》是一本深入探讨存储技术的专业书籍,由一位对技术充满热情的作者精心撰写。这本书以其严谨的态度和丰富的想象力,揭示了存储系统的底层奥秘,旨在帮助读者全面...
大话存储:存储系统底层架构原理极限剖析(终极版)第4部分 大话存储:存储系统底层架构原理极限剖析(终极版)第4部分
《大话Oracle RAC:集群 高可用性 备份与恢复》以Oracle 10g为基础,对Oracle RAC进行了全面的介绍和分析。全书分为两个部分,共14章,第1部分是集群理论篇,这部分从集群基础知识入手,通过分析集群环境和单机环境...
Tableau是一款强大的商业智能工具,它允许用户通过直观的拖放界面来探索和可视化数据,从而揭示隐藏在大量数据背后的模式、趋势和洞察。 在进行Tableau数据可视化时,首先需要理解数据集的结构和内容。数据集通常...
大话存储2:存储系统架构与底层原理极限剖析》内容简介:网络存储是一个涉及计算机硬件以及网络协议/技术、操作系统以及专业软件等各方面综合知识的领域。目前国内阐述网络存储的书籍少之又少,大部分是国外作品,对...
4. **大话工具箱**:这是一个综合性的辅助工具集合,可能包括自动挂机、任务助手、属性计算等功能,旨在简化游戏中的繁琐操作,提高游戏效率。 5. **Was_Tools**:可能是针对游戏服务器的管理工具,比如数据库备份...
- **文件结构分析**:工具首先需要理解.wdf文件的内部结构,包括数据块的排列方式、资源的编码规则等,这通常涉及到逆向工程的技术。 - **解码算法**:不同的.wdf文件可能使用不同的压缩和加密算法,工具需要有...
大话存储:存储系统底层架构原理极限剖析(终极版)第3部分 大话存储:存储系统底层架构原理极限剖析(终极版)第3部分大话存储:存储系统底层架构原理极限剖析(终极版)第3部分
《大话西游素材查看工具详解与应用》 在游戏开发和设计领域,素材管理是一项至关重要的工作。尤其是在中国的网络游戏领域,"大话西游"作为一款深受玩家喜爱的经典游戏,其背后的素材制作与管理自然也备受关注。本文...
《大话梦幻工具.zip》是一个综合性的资源包,包含了与“大话西游”和“梦幻西游”这两款著名网络游戏相关的各种辅助工具和素材。这个压缩包的主要目的是为玩家和开发者提供方便,帮助他们在游戏中进行更高效的操作或...
功能: 支持AS3的ByteArray序列化对象的AMF格式编码、解码( readObject、writeObject )。 支持AS3的ByteArray的compress、uncompress压缩算法:DEFLATE、LZIB、LZMA。 支持直接修改AS3的ByteArray字节流内编码...
8. **输出工具**:可能用于将处理后的素材导出为游戏可识别的格式,或者将修改结果应用回游戏中。 9. **wastool**:这可能是一个通用的WAS文件处理工具,可以进行解包、打包等操作。 10. **梦幻棱镜**:可能是梦幻...