分享
 
 
 

《重构》读书笔记(一)

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

前几天,从同事那里借来Matin Fowler的《重构》一书,看得我很是过瘾。尽管看后印象颇深,但要作到过目不忘是不可能的,故将书中自己认为重要的东西记录下来。俗话说的好:好记性不如烂笔头。

注:很多直观的重构方法没有做解释,从其名字就可以猜出其用法。

重新组织你的函数

==========================================================

1.Extract Method

2.Inline Method

3.Inline Temp

4.Replace Temp with Query

临时变量的问题在于:它们是暂时的,只能在函数内部使用,这驱使你写出更长的函数,

因为只有这样你才能访问到你要访问的临时变量。如果采用该方法,那么同一个Class中

的所有函数都可以获得这份信息。这将给你极大的帮助,使你能够为这个Class编写更清

晰的代码。

将只被赋值一次的临时变量的赋值操作提炼到独立函数中,然后在该临时变量上实施

Inline Temp.

例:

// 原函数

double getPrice(){

int basePrice = _quatity * _itemPrice;

double discountFactor;

if (basePrice > 1000) discountFactor = 0.95;

else discountFactor = 0.98;

return basePrice * discountFactor;

}

// 替换basePrice

double getPrice(){

double dicountFactor;

if (basePrice() > 1000) discountFactor = 0.95;

else discountFactor = 0.98;

return basePrice() * discountFactor;

}

int basePrice(){

return _quatity * _itemPrice;

}

// 替换discountFactor

double getPrice(){

return basePrice() * discountFactor();

}

int basePrice(){

return _quatity * _itemPrice;

}

double discountFactor(){

if (basePrice() > 1000) return 0.95; // 从上次替换中获得好处

else return 0.98;

}

5.Introduce Explaining Variable

6.Split Temperary Variable

7.Remove Assignments to Parameters

不要对参数赋值

8.Replace Method with Method Object

将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域(field)。

然后你可以在同一个对象中将这个大型函数分解为小型函数。

9.Substitue Algorithm

替换你的算法

在对象之间搬移特性

==========================================================

1.Move Method

在你的程序中,有个函数与其所在class之外的另一个class进行更多交流:调用后者,

或被后者调用。

减小类之间的耦合。

步骤:

考虑source class定义的source method所使用的一切特性是否也应该搬移。

如果source class的subclass和superclass有其声明,或许无法搬移,除非

target class也同样表现出多态性。

在target class中新建函数,然后将source method的代码复制到target method

决定如何从source正确引用target object。

修改source method,使之成为一个delegating method。

决定是否删除source method,看是否方便。

如果删除,则将对source method的调用替换为对targetobject.targetmethod的

调用。

2.Move Field

3.Extract Class

4.Inline Class

5.Hide Delegate

将调用Server.delegate.someMethod()变为Server.someMethod()。

去除调用方对Server.delegate的依赖。

6.Remove Middle Man

7.Introduce Foreign Method

时机:你所使用的server class需要一个额外函数,但你无法修改这个class。

如果你发现自己已经为server class建立了大量的外加函数,或有许多class都需要

同样的外加函数,你就不应该使用本方法,而应该使用Introduce Local Extesion。

步骤:

在client class中建立一个函数,用来提供你的功能。该函数不应该去用client class

的任何特性,如果需要一个值,就将其当作参数传给它。

以server class实体为该函数的第一个参数。

将该函数注释为:外加函数,应在server class实现。

8.Introduce Local Extension

时机:见7.Introduce Foreign Method

方法:建立新类,其中包括那些额外函数,使该类成为source class的subclass或wrapper。

重新组织数据

==========================================================

1.Self Encapsulate Field

封装的好处:subclass可以通过覆写读取、写入函数来改变数据读取、写入的逻辑方式

不封装的好处:简单

2.Replace Data Value with Object

比如说:一开始你会用字符串来表示『电话号码』这个概念,但随后你会发现,电话号码需要『格式化』、

『抽取区号』之类的特殊行为。如果这样的数据项只有一二个,你还可以把相关函数放进数据项所属的对象

里头;但是Duplicate Code臭味和Feature Envy臭味很快就会从代码中散发出来。当这些臭味开始出现,

你就应该将数据值变成对象。

3.Change Value to Reference

将这个value object(实值对象)变成一个Reference object(引用对象)

4.Change Reference to Value

5.Replace Array with Object

6.Duplicate Observed Data

重复的意思:界面类中有的数据,逻辑类也有相同的数据。

其中运用了Observer模式来同步界面类和逻辑类的数据。

可以用于界面与逻辑分开。

需要进一步研究

7.Change Unidirectional Association to Bidirectional

8.Change Bidirectional Association to Unidirectional

9.Replace Magic Number with Symbolic Constant

10.Encapsulate Field

11.Encapsulate Collection

12.Replace Record with DataClass

13.Replace Type Code with Class

枚举型数据的替代方案

class BloodGroup{ // 血型

public static final BloodGroup O = new BloodGroup(0);

public static final BloodGroup A = new BloodGroup(1);

public static final BloodGroup B = new BloodGroup(2);

public static final BloodGroup AB = new BloodGroup(3);

private final int _code;

private BloodGroup(int code){

_code = code;

}

}

14.Replace Type Code with Subclasses

你有一个不变的type code,它会影响class的行为。

类似于状态处理机模式

15.Replace Type Code with State/Strategy

你有一个type code,它会影响class的行为,但你无法使用subclassing.

比如:type code 在对象生命周期中发生变化。

state object对应的Field可以替换成其他state object

16.Replace Subclass with Fields

简化条件表达式

==========================================================

1.Decompose Conditional(分解条件式)

将其分解成多个独立函数

2.Consolidate Conditional Expression(合并条件式)

合并不必单独存在的条件式

3.Consolidate Duplicate Conditional Fragments(合并重复的条件片断)

在条件式的每个分支上有着相同的一段代码。进行该重构,可以更好的表明那些东西

随条件的变化而变化。

4.Remove Control Flag

循环语句中,最好用Break或Exit取代控制标记(用来判断是否继续循环)

5.Replace Nested Conditional with Guard Clauses

以卫语句取代嵌套条件式

函数中的条件式使人难以看清正常的执行路径。

给某一条分支以特别的重视。

条件式通常有两种形式:一是所有分支都是正常行为;二是只有一种是正常行为,其他

都是不常见的情况。

卫语句最好返回一个明确值,以便看得更清楚。

// 原代码

double getPayAmount(){

double result;

if (_isDead) result = deadAmout();

else {

if (_isSeparated) result = separatedAmount();

else {

if (_isRetired) result = retiredAmount();

else result = normalPayAmount();

}

}

}

// 新代码

double getPayAmount(){

if (_isDead) return deadAmount();

if (_isSeparated) return separatedAmount();

if (_isRetired) return retiredAmount();

return normalPayAmount();

}

6.Replace Conditional with Polymorphism

以多态取代条件式

多态最根本的好处是:如果你需要根据对象的不同型别而采取不同的行为,多态使你不必编写

明显的条件式。

7.Introduce Null Object

将null value替换为null object

比如想显示一个Persion对象信息,它大约有20个instance变量。如果这些变量可被设为null,

那么打印一个Person对象的工作将非常复杂。如果将null value换成null object(他们都知道如

何正常地显示自己),Person类就可以减少很多代码。

比Null Object模式更大的模式:Specail Case模式。

步骤:

1.为source class建立一个subclass,其行为像source class的null版本。在source class

和subclass中都加上isNull()函数,前者返回false, 后者返回true。

2.找出所有取得source object却取得null的地方。修改它,使其获得null object。

3.找出所有『将source object与null比较』的地方,使他们调用isNull()函数。

4.找出这样的程序点:如果对象不是null, 做A动作,否则做B动作。

5.对于每一个这样的地方,在null class中覆写A动作,使其行为和B动作相同。

6.删除isNull()的条件判断。

8.Introduce Assertion

以断言明确表现这种假设。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有