重构 -改变既有代码的设计 ---- 笔记
目录
- 1. TABLE OF CONTENT
-
3. BAD SMELLS IN CODE(代码的坏味道)
- 1. Duplicated code (重复的代码)
- 2. Long Method(很长的方法)
- 3. Large Classes(超级大的类)
- 4. Long Parameter List(长参数列表)
- 5. Divergent Change(发散的改变)
- 6. Shotgun Surgery(散弹枪修改)
- 7. Feature Envy(依恋情结)
- 8. Data Clumps(数据泥团)
- 9. Primitive Obsession(基本类型偏执)
- 10. Switch Statements(Switch 惊悚现身)
- 11. Parallel Inheritance Hierarchies(平行继承类)
- 12. Lazy Class(冗余类)
- 13. Speculative Generality(夸夸其谈未来性)
- 14. Temporary Field(令人迷惑的临时变量)
- 15. Message Chain(过长的消息链)
- 16. Middle Man(中间人)
- 17. Inappropriate Intimacy(不恰当的亲密关系)
- 18. Alternative Classes with Different Interfaces(异曲同工的类)
- 19. Incomplete Library Class(不完美的库)
- 20. Data Class(数据类)
- 21. Refused Bequest(被拒绝的遗赠)
- 22. Comments(过多没用的注释)
-
6. COMPOSING METHODS(重新组织函数))
- 1. Extract Method(提炼函数)
- 2. Inline Method (内联函数)
- 3. Inline Temp (内联临时变量)
- 4. Replace Temp with Query (以查询取代临时变量)
- 5. Introduce Explaining Variable (引入解释性变量)
- 6. Split Temporary Variable (分解临时变量)
- 7. Remove Assignments to Parameters(移除对参数的赋值)
- 8. Replace Method with Method Object (以函数对象取代函数)
- 9. Substitute Algorithm (算法替换)
- 7. Moving features between elements(移动对象)
-
8. ORGANIZING DATA (组织数据)
- 18. Self Encapsulate Field (对字段获取进行封装)
- 19. Replace Data Value with Object (用对象替换数据值)
- 20. Change Value to Reference (将值改为引用)
- 21. Change Reference to Value (将引用改为值)
- 22. Replace Array with Object (用对象代替数组)
- 23. Duplicate Observed Data (监控数据对象)
- 24. Change Unidirectional Association to Bidirectional(将单向联系改为双向联系)
- 25. Change Bidirectional Association to Unidirectional (将单向改为双向的联系)
- 26. Replace Magic Number with Symbolic Constant (使用符号来替代魔法字符串)
- 27. Encapsulate Field (封装字段)
- 28. Encapsulate Collection (封装集合)
- 29. Remove Record with data class (在数据类中移除 记录值)
- 30. Replace Type Code with Class (使用类来替代类别代码)
- 31. Replace Type Code with Subclasses (使用子类来替代类别代码)
- 32. Replace Type Code with State/Strategy(通过状态模式或者策略模式来代替类型码)
- 32. Replace Subclass with Fields(用字段代替子类)
-
9. SIMPLIFYING CONDITIONAL EXPRESSIONS(简化条件表达式)
- 33. Decompose Conditional (分解条件)
- 34. Consolidate Conditional Expression
- 35. Consolidate Duplicate Conditional Fragments (合并重复的条件片段)
- 36. Remove Control Flag (移除控制标记)
- 37. Replace Nested Conditional with Guard Clauses (以卫语句取代嵌套的条件表达式)
- 38. Replace Conditional with Polymorphism (以多态取代条件表达式)
- 39. Introduce Null Object (引入Null 对象)
- 40. Introduce Assertion (引入断言)
-
10. MAKING METHOD CALLS SIMPLER (简化函数的调用)
- 41. Rename method (函数改名)
- 42. Add Parameter (添加参数)
- 43. Remove Parameter(移除参数)
- 44. Separate Query from Modifier (将查询函数和修改函数分离)
- 45. Parameterize Method (令函数携带参数)
- 46. Replace Parameter with Explicit Methods (已明确函数取代参数)
- 47. Preserve Whole Object (保持对象的完整)
- 48. Replace Parameter with Method (已函数取代参数)
- 49. Introduce Parameter Object (引入参数对象)
- 50. Remove Setting Method (移除设值函数)
- 51. Hide Method (隐藏函数)
- 52. Replace Constructor with Factory Method (已工厂函数取代构造函数)
- 53. Encapsulate Downcast (封装向下转型)
- 54. Replace Error Code with Exception (以异常取代错误码)
- 55. Replace Exception with Test (已测试取代异常)
-
11. DEALING WITH GENERALIZATION (处理概括关系)
- 56. Pull up field (字段上移)
- 57. Pull Up Method (构造函数本体上移)
- 58. Pull Up Constructor Body (构造函数本体上移)
- 59. Push Down Method (方法下移)
- 60. Push Down Field (字段下移)
- 61. Extract Subclass (提炼子类)
- 62. Extract Superclass (提炼超类)
- 63. Extract Interface (提炼接口)
- 64. Collapse Hierarchy (折叠继承体系)
- 65. Form Template Method (塑造模板函数)
- 66. Replace Inheritance with Delegation (以委托取代继承)
- 67. Replace Delegation with Inheritance (以继承取代委托)
- 12. BIG REFACTORINGS (大型重构)
这是一篇《重构 》的总结 ,我在学习的同时并使用它作为参考。这不是一本书的替代品,所以你要想真的想学习里面的内容,买一本书使用这个文章作为参考和指南。
另外: 建议 评论 还 PR 都是十分欢迎的
1. TABLE OF CONTENT
3. BAD SMELLS IN CODE(代码的坏味道)
1. Duplicated code (重复的代码)
多个地方使用相同的代码
2. Long Method(很长的方法)
一个很长的程序是很难被理解的
3. Large Classes(超级大的类)
当一个类变的越来越大的时候,是难以阅读的
4. Long Parameter List(长参数列表)
长参数是很难去理解,不符合也较难使用
5. Divergent Change(发散的改变)
当一个类经常因为不同原因发生在不同的方向发生变化
6. Shotgun Surgery(散弹枪修改)
每次你做一小部分修改时,都不的不需要做大量的修改在很多不同的类中
7. Feature Envy(依恋情结)
某个方法似乎在另外的类的兴趣高于自己所处的类
8. Data Clumps(数据泥团)
一堆数据杂糅在一起(字段, 参数)
9. Primitive Obsession(基本类型偏执)
使用基本类型替代小对象
10. Switch Statements(Switch 惊悚现身)
当程序中出现很多 switch 语句在很多地方,使用多态来进行替换
11. Parallel Inheritance Hierarchies(平行继承类)
每当你为一个类增加一个子类,你不得不为另一个类增加相应的一个子类
12. Lazy Class(冗余类)
当一个类不足与为其自身买单它就应该被删除
13. Speculative Generality(夸夸其谈未来性)
所有的钩子和特殊情况处理那些不需要的
14. Temporary Field(令人迷惑的临时变量)
一个临时变量仅仅为某种特殊情况做而定,这样的代码让人难以理解
15. Message Chain(过长的消息链)
当一个类请求调用一个对象,但是这个类又在调用其他的方法
16. Middle Man(中间人)
当一个对象委托大部分功能,开发中可能会过度的使用委托模式,导致某个类中的方法大都委托给其他方法处理
17. Inappropriate Intimacy(不恰当的亲密关系)
当两个类过度的亲密,需要将其拆散
18. Alternative Classes with Different Interfaces(异曲同工的类)
类的方法过度相似
19. Incomplete Library Class(不完美的库)
当我们使用外部依赖库时
20. Data Class(数据类)
不要操作数据类,我们通过封装它的不变性
21. Refused Bequest(被拒绝的遗赠)
子类不想使用父类的方法
22. Comments(过多没用的注释)
当一个方法使用过度的注释解释其中的逻辑时,说明这个方法应该被重构了。
6. COMPOSING METHODS(重新组织函数))
1. Extract Method(提炼函数)
你可以将一些代码组合起来,然后放到一个方法中
void printOwing(double amount) {
printBanner();
//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}
to
void printOwing(double amount) {
printBanner();
printDetails(amount);
}
void printDetails (double amount) {
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}
动机
- 增加代码被复用的机会
* 阅读方法就像阅读一系列声明一样简单
void printOwing(double previousAmount) {
Enumeration e = _orders.elements();
double outstanding = previousAmount * 1.2;
printBanner();
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
printDetails(outstanding);
}
to
void printOwing(double previousAmount) {
printBanner();
double outstanding = getOutstanding(previousAmount * 1.2);
printDetails(outstanding);
}
double getOutstanding(double initialValue) {
double result = initialValue;
Enumeration e = _orders.elements();
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}
2. Inline Method (内联函数)
一个函数本体和函数名称一样容易理解
int getRating() {
return (moreThanFiveLateDeliveries()) ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
return _numberOfLateDeliveries > 5;
}
to
int getRating() {
return (_numberOfLateDeliveries > 5) ? 2 : 1;
}
动机
- 当间接不是必要的时候
- 当一组方法被严格的分解,会使这个方法变得清晰
3. Inline Temp (内联临时变量)
你申明了一个临时的变量在一段表达里面,然后临时的变量将会阻挡你重构
double basePrice = anOrder.basePrice();
return (basePrice > 1000)
to
return (anOrder.basePrice() > 1000)
Motivation
- Use it with 4. Replace Temp with Query
- 使用这个 4. Replace Temp with Query
4. Replace Temp with Query (以查询取代临时变量)
你正在使用临时变量来保存表达式的结果
double basePrice = _quantity * _itemPrice;
if (basePrice > 1000){
return basePrice * 0.95;
}
else{
return basePrice * 0.98;
}
to
if (basePrice() > 1000){
return basePrice() * 0.95;
}
else{
return basePrice() * 0.98;
}
...
double basePrice() {
return _quantity * _itemPrice;
}
动机
- 使用方法代替临时变量,类中的任何方法都可以获取信息
- 这是一个十分重要的步骤在其之前1. Extract Method
5. Introduce Explaining Variable (引入解释性变量)
有一个复杂的表达式
if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0 )
{
// do something
}
to
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") >-1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") >-1;
final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// do something
}
动机
- 当一个表达式难以理解时