Board logo

标题: 从Java的角度理解设计模式(连载) [打印本页]

作者: jiameng1987    时间: 2009-6-19 16:43     标题: 从Java的角度理解设计模式(连载)

从Java的角度理解设计模式1:什么是重构


MF在《重构》一书中是这样定义重构的:重构是这样一个过程,在不改变代码外在行为的前提下,对代码作出修改,以改进程序的内部结构。重构是一种有纪律的、经过训练的、有条不紊的程序整理方法,可以将整理过程中不小心引入错误的机率降到最低。本质上说,重构就是在代码写好之后改进它的设计。
通常,软件开发总是先设计后编码,然而难免地,程序员编码风格的随意性、系统庞大化等诸多因素,导致代码质量将变得愈发难以控制。重构使得即使在面对糟糕设计,甚至是代码一片混乱的情况下,也能逐步改良代码的设计。大多数重构的步骤非常简单,比如为一个方法添加一个参数(Refactoring:Add Parameter)、(在类间)搬动一个方法(Refactoring :Move Method)、在类阶层中上下迁移代码:如值域(Refactoring :Push Up/Down Field)。然而正是这些微小的步骤,保障了代码朝着优良的结构持续演变,或者说不会日益“腐烂”。
此外,重构的工作方法也使得所谓的精心设计不再如此举足轻重了,因为设计可以在持续重构中得到强化。
如下展示了一个非常简单的重构,它采用了(Refactoring:Add Parameter):
private void mainTestBody() {
ApplicationContext context =
new ClassPathXmlApplicationContext("ch6/prototype/setter-injection.xml");
BookList booklist = (BookList)context.getBean("bookList");
Book[] books = booklist.findBooksWrittenBy("天下霸唱");
assertEquals("鬼吹灯",books[0].getName());
}




private void mainTestBody(String configMetadata) {
ApplicationContext context =
new ClassPathXmlApplicationContext(configMetadata);
BookList booklist = (BookList)context.getBean("bookList");
Book[] books = booklist.findBooksWrittenBy("天下霸唱");
assertEquals("鬼吹灯",books[0].getName());
}
本书对于重构剖析的侧重点有两个:一个是如何将重构应用于Java模式和框架设计的编程中;一个则是如何利用自动化重构工具对代码实施重构(当然并不是所有的重构技巧都得到工具支持)。
本书对重构提供的阅读方法是:本章将会列出所有本书中用到的重构技巧名录(按字母顺序排列),而在后续各个章节中,对这些重构技巧的应用时机和方法会有更贴近实际的讲解;关于自动化重构工具的使用仅在本章列出,在后续章节中如果希望得到自动化的重构指导(对于每个重构技巧,如果自动化重构工具支持的话,都会有相应的指导),可参考本章。
作者: jiameng1987    时间: 2009-6-19 16:43     标题: 从Java的角度理解设计模式2:自动化重构工具的使用

重构的理论很具有吸引力,然而纯手工的重构需要检查的东西相当多,是一项耗时、易错的工作。也因为这个原因,很多程序员觉得重构的成本太大而不愿意进行重构。自动化重构工具的出现,大大改善了这个局面。现代化IDE融入重构功能后,使得编程和重构之间的差异也日益缩小(程序员几乎不再需要分辩“正在编程”还是“正在重构”),许多自动化的重构甚至基本都无须测试,重构成本也因此大大降低。
Java语言语法简洁清晰,是非常便于重构的一门语言,本书介绍的自动化重构工具便是一款成熟的Java IDE:Eclipse(使用的版本是3.3),读者可在http://www.eclipse.org/downloads/ 下载到Eclipse的最新版本。
作者: jiameng1987    时间: 2009-6-22 14:02     标题: 从Java的角度理解设计模式3:自动提炼方法

下面将简单展示两个重构技巧“提炼方法(Refactoring:Extract Method)”和“搬移方法(Refactoring:Move Method)”如何通过Eclipse自动实施。给出原始代码,如下所示。
HelloBean.java
package ch2.extractandmovemethod.prototype;

public class HelloBean {
public void sayHello() {
System.out.println("朋友,时刻重构吧!");
}
}
RefactoringIDETest.java
package ch2.extractandmovemethod.prototype;

public class RefactoringIDETest {
public static void main(String[] args) throws Exception {
String className = "ch2.refactoringusingide.HelloBean";
Object beanInstance = null;
try {
Class clazz = Class.forName(className);
beanInstance = clazz.newInstance();
} catch (Exception ex) {
throw ex;
}
((HelloBean)beanInstance).sayHello();
}
}
注意上述代码的框选部分,显然这部分代码可以被提炼出来形成一个公用方法。
说明:如果使用重构工具,只需简单地圈选出要提炼的段落,然后点选菜单选项“Extract Method”就行了。重构工具会自动检查被圈选的代码段是否可以提炼。代码无法提炼的原因有很多,可能是:它可能只包含部分标识符声明;可能对某个变量赋值而该变量又被其它代码用到。所有这些情况,程序员都完全不必担心,因为重构工具会自动识别并处理一切。随后,工具会自动计算出新方法所需的参数,并要求程序员为新方法取一个名字。此时,程序员可自行决定新方法参数的命名、排列顺序等。所有准备工作都完成后,重构工具会把圈选的代码从源方法中提炼出来,并在源方法中加入对新方法的调用。随后它会再源方法所属的类中建立新的方法,并以程序员指定的名称来命名该方法。整个重构过程耗时极短,且不会出错,相比手工进行这个重构,方便、安全了许多,体现了自动化重构工具的威力。
现在用Eclipse来实现上述步骤,首先选中上述代码的框选部分,点击鼠标右键,找到重构菜单“Refactor”,点选“Extract Method” (注意,重构菜单会自动识别出当前圈选的代码段有哪些重构技巧可用),如图1所示。
图1 自动化重构过程第一步
在随后出现的对话框中,为提炼出的新方法命名(命名为“instantiateClass”),并决定其它的方法签名(注意,为了后续可以不用修改地将此方法搬移到另一个工具类中,请选择“public”的方法访问权限),如图2所示。
图2 自动化重构过程第二步
点选“Preview”可预览重构所牵动的资源和结果,点选“OK”将直接进行重构,点选“Cancel”将放弃重构,当然即使在重构完成后,Eclipse也提供了强大的重构回复功能,可将所有牵动的代码回复到重构前的状态,甚至还有重构的历史回复功能。现在,点击“OK”,得到应用了(Refactoring:Extract Method)后的代码,如下所示。
RefactoringIDETest.java
package ch2.extractandmovemethod;

import ch2.extractandmovemethod.prototype.HelloBean;

public class RefactoringIDETest {
public static void main(String[] args) throws Exception {
String className = "ch2.refactoringusingide.HelloBean";
Object beanInstance = instantiateClass(className);
((HelloBean)beanInstance).sayHello();
}

public static Object instantiateClass(String className) throws Exception {
Object beanInstance = null;
try {
Class clazz = Class.forName(className);
beanInstance = clazz.newInstance();
} catch (Exception ex) {
throw ex;
}
return beanInstance;
}
}



融智技术学苑(http://www.rzchina.net)版权所有,本公司致力于提供更好更实用的Java培训课程,帮助学员迅速成为编程的行家里手,更多Java面试题\Java视频\Java教程请访问我们的网站.转载请保留这段文字。
作者: jiameng1987    时间: 2009-6-23 11:15     标题: 从Java的角度理解设计模式5:自动改变方法签名

从Java的角度理解设计模式5:自动改变方法签名
(Refactoring:Change Method Signature)其实是Eclipse组合了《重构》一书中的几个重构技巧而成,它们分别是Add/Remove Parameter(增加/移除 方法参数)、Rename Method(重命名方法)。
1.动机
方法签名包含方法名、参数列(类型和次序)、方法返回类型、方法访问权限等,在编程的时候,改变方法签名有各种动机,比如当发现方法的名称未能明确揭示方法用途时,则需要改变方法名称(Refactoring:Rename Method);当发现某个方法需要从调用端得到更多信息时,则需要为方法添加参数(Refactoring:Add Parameter,见2.1节示例);当发现方法本体不再需要某个参数时,就需要移除参数(Refactoring:Remove Parameter),冗余的参数往往会给客户带来负担。
2.作法
以上这些重构技巧,在Eclipse中都可以通过重构菜单“Change Method Signature”来一并完成。给出原始的类,如下所示。

BeanFactory.java

package ch2.changemethodsignature.prototype;

import ch2.utils.BeanUtils;

public class BeanFactory {
public Book getBook() throws Exception {
return (Book)BeanUtils.instantiateClass(
"ch2.changemethodsignature.prototype.Book");
}
}
显然getBook()作为BeanFactory的主力工厂方法它不够通用,因此需要适当改变它的方法签名和实现。现在用Eclipse来实现上述步骤,首先双击选中getBook()方法,点击鼠标右键,找到重构菜单“Refactor”,点选“Change Method Signature”,在随后出现的对话框中,为getBook()方法重命名(命名为“getBean”);调整它的返回值为“Object”、访问权限为“public”;增加两个String型的参数“packageName”和“className”,如图5所示。

图5 自动改变方法签名
去掉方法内的强制转型后,得到初步重构后的代码,如下所示。

BeanFactory.java

public class BeanFactory {
public Object getBean(String packageName, String className) throws Exception {
return BeanUtils.instantiateClass(packageName + className);
}
}
发现方法参数冗余,使用一个Bean的标识符就足够了。迅速作出再次重构,通过Eclipse的“Change Method Signature”菜单去掉一个参数(使用图5中的Remove按钮),并改变参数名称,得到最后的代码,如代码所示。

代码 BeanFactory.java

package ch2.changemethodsignature;

import ch2.utils.BeanUtils;

public class BeanFactory {
public Object getBean(String beanIdentifier) throws Exception {
return BeanUtils.instantiateClass(beanIdentifier);
}
}




融智技术学苑(http://www.rzchina.net )版权所有,本公司致力于提供更好更实用的Java培训课程,帮助学员迅速成为编程的行家里手,更多Java面试题\Java视频\Java教程请访问我们的网站.转载请保留这段文字。




欢迎光临 编程开发论坛 (http://bbs.lihuasoft.net/) Powered by Discuz! 6.0.0