分享
 
 
 

重构--refactoring(1)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

写在文章之前

一直想读这本书,但总是没有机会寻到,现偶然得到,细细读

来倍感激动,有如当年初读设计模式时的兴奋。独乐乐,不如同乐。

感尚无中文版本,所以小弟不才,翻译与大家同读。此地卧虎藏龙,

英文好我者不胜枚举,若有翻译不妥之处还请见谅。支持者UP一下

即可。

第一章: 重构,第一个例子

该如何开始写重构这本书呢?传统的方式是列出历史提纲、广

泛的原则等。当一些人在会议上开始这么做的时候,我则有些轻微的

睡意。面对讲演者 的陈词滥调我的头脑开始思考在较低层次的

处理上,直到她或他给出一个例子。 这将把我从昏昏欲睡中唤

醒,有一个例子能够使我知道下一步该干什么.用原理,太简单以至

于一般化,太难了很难指出该如何应用。而一个例子将会使问题变得

更清晰。

因此,我打算从一个重构的例子开始本书。在这个过程中,我将告诉

你如何重构以及让你对重构处理一个感性的认识。这样接下来能让我

提供一个通常的原理风格上的介绍。

然而,随着一个例子的引入,我将碰上一个一个大问题。如果我选择

一个大程序,描述她如何重构,这对于打多数的读者来说过于复杂以

至于不能完成工作。(我尝试后发觉即便是一个轻微复杂的例子也超

过100页)另一方面,如果我选择一个容易被理解的小程序,那会使

得重构看起来没有价值。

因此,我将使用经典著作中的方式通过引入一个真实世界中的程序来

描述这门技术。坦白的说,我展示给你的一段我打算使用的小程序对

她重构是没有什么价值的,但是如果我展示给你的是一个大系统中的

一段代码,那么重构不久将变得重要。所以我不得不要求你将它看作

是一个大系统中的一部分。

开始点

程序非常简单。他计算并打印一名客户在录像带出租店的收费情况。

程序输入客户借阅的电影和借阅时间。通过借阅的日期长度和借阅的

电影类型来计算收费。这儿有三种类型的影片:通常、儿童、新片。

另外通过计算费用,可以估租借热点,不在依赖于电影是否是新版。

下面几个类将代表不同的元素,类图如下所示:

图1.1 开始点得类图,仅最重要的特性被描述。使用UML符号。

我将轮流展示这些类的代码。

Movie

Movie是一个简单得类。

public class Movie{

public static final int SHILDRENS =2;

public static final int REGULAR =0;

public static final int NEW_RELEASEE =1;

private String _title ;

private int _priceCode ;

public Movie(String title,int priceCode){

_title = title ;

_priceCode = priceCode;

}

public int getPriceCode(){

return _priceCode;

}

public void setPriceCode(int arg){

_priceCode = arg;

}

public void getTitle(){

return _title;

}

}

Rental

Rental 代表一个客户借一部电影

class Rental {

private Movie _movie;

private int _daysRented;

public Rental(Movie movie,int daysRented){

_movie = movie;

_daysRented = daysRented;

}

public int getDaysRented(){

return _daysRented;

}

public Movie getMovie(){

return _movie;

}

}

Customer

Customer 代表录像店的一个客户,像其她的类一样她也有所数据和访问器。

class Customer{

private String _name;

private Vector _rentals = new Vector();

public Customer(String name){

_name = name;

}

public void addRental(Rental arg){

_rentals.addElement(arg);

}

public String getName(){

return _name;

}

}

Customer有一个方法实现 statement(收费情况)。图:1.2表明了这些方法

的交互。这个方法的主体是一个界面。

图1.2statement方法的交互图。

public String statement(){

double totalAmount =0;

int frequentRenterPoints =0;

Enumeration rentals = _rentals.elements();

String result ="Rental Record for "+getName()+"\n";

while(rentals.hasMoreElements()){

double thisAmount =0;

Rental each = (Rental)rentals.nextElement();

switch(each.getMovie().getPriceCode()){

case Movie.REGULAR:

thisAmount+=2;

if(each.getDaysRented()>2)

thisAmount+=(each.getDaysRented()-2)*1.5;

break;

case Movie.NEW_RELEASE:

thisAmount+=each.getDaysRented()*3;

break;

case Movie.CHILDRENS:

thisAmount+=1.5;

if(each.getDaysRented()>3)

thisAmount+=(each.getDaysRented()-3)*1.5;

break;

}

frequentRenterPoints++;

if((each.getMovie.getPriceCode()==Movie.NEW_RELEASE)&&

each.getDaysRented()>1)

frequentRenterPoints++;

//show figures for this rental

result+="\t"each.getMOVIE().getTitle()+"\t"+

String.valueOf(thisAmount)+"\n";

totalAmount += thisAmount;

}

//add footer lines

result+="Amount owed is "+ String .valueOf(totalAmount)+"\n";

result+="You earned "+String.valueOf(frequentRenterPoints)+

"frequent renter points";

return result;

}

关于这个程序

你对这个程序设计有什么印象?我对他的看法是他不是一个好的设计

并且也不是面向对象的。对于一个像这样的简单程序来说,这并不重要。

作为一个敏捷和不清晰的简单例子来说本身没有任何错误。但是如果这

是一个大系统的一部分,那么这个程序会有一些问题。statemetn方

法在Customer类中走得太远了。许多工作因该在其他类中来做。

即便程序能够工作。你是否愿意对丑陋的代码作美化呢?还是直到我们

改变系统。编译器是不会知道代码是否丑陋或清晰。当时当我改变一个

系统的时候,我们将卷入到系统中,我们会注意到这一点。一个糟糕的

设计很难被改变,因为很难指出到底那里需要被改变。如果难于指出要

改变什么,那么程序员将会犯错误或是引入新的BUG。

在这个例子中,我们将转变用户的想法。首先:用户想能够在WEB

上发布有关资费信息以满足客户的抱怨。考虑到这种改变,你要查看

你的源代码,看看是否有可能重用你的当前statement 方法的行为来

满足HTMLStatement。你唯一可行的方法是重新写具有相同特性的整

个方法,当然,这并不费力气,通过拷贝粘贴即可实现你的要求。

但是当收费规则改变呢?你不得不修改statement和HTMLStatement,以

确保他们在一致。问题是当以后再一次改变时,你不得不再一次拷贝很

粘贴代码。如果你期望你的程序不会再被改动,那么拷贝很粘贴是不错

的方法,但如果你的程序未来会被修改,那么拷贝很粘贴将带来混乱。

我们来介绍第二种改变。用户想法变电影分类方法,但是他们无法立即

决定下来,而是留待以后再决定。他们对此头脑中有一个想法。这些改

变将影响到出租方式、出租频率点数的计算。作为一个有经验的开发人

员,你应当更当上用户的计划,而

不是让你的计划停留在6个月内。

statement方法应该能够应付对于非类方法和收费规则的改变。但如果我

采取从statemet方法拷贝很粘贴到HTMLStatemtn我们他们的一致性。未

来随着规则的进一步复杂化,我们将很难指出到底那里被改变了,也很

难保证不引入新的错误。

你也许试图作经可能小的改变,毕竟她已经你能够工作。记一句古老的

工程谚语:“如果他自己破了,不要试图去修改她。“这个程序也许没

有破,但是他是有害的。当你发觉他不能适应用户的要求时,它会给你

带来困难。这就是为什么要重构。

提示

当你发现程序的结构不方便增加一个特性,而你不得不给程序增加一个

特性时,重构程序是它容易添加新特性,然后添加你的新

特性.

重构的一步。

待续。。。。。。。。。。。。。。。。。。。。。。。。。。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有