一、Replace Exception with Test(以测试取代异常)
动机(Motivation)
面对一个[调用者可预先加以检查]的条件,你抛出了一个异常。修改调用者,使它在调用函数之前先做检查。
示例
01 |
private Dictionary< int , string > _values; |
02 |
03 |
public double GetValueForPeriod( int periodNumber) |
04 |
{ |
05 |
try |
06 |
{ |
07 |
return _values[periodNumber]; |
08 |
} |
09 |
catch |
10 |
{ |
11 |
return 0; |
12 |
} |
13 |
} |
改为
1 |
private Dictionary< int , string > _values; |
2 |
3 |
public double GetValueForPeriod( int periodNumber) |
4 |
{ |
5 |
if (_values.ContainsKey(periodNumber)) |
6 |
return _values[periodNumber]; |
7 |
return 0; |
8 |
} |
二、Pull Up Field(值域上移)
动机(Motivation)
两个subclasses拥有相同的值域,将此一值域移至superclass。
示例
01 |
public abstract class Emplayee |
02 |
{ |
03 |
04 |
} |
05 |
06 |
public class Salesman : Emplayee |
07 |
{ |
08 |
private string _name; |
09 |
10 |
public string Name |
11 |
{ |
12 |
get { return _name; } |
13 |
set { _name = value; } |
14 |
} |
15 |
} |
16 |
17 |
public class Engineer : Emplayee |
18 |
{ |
19 |
private string _name; |
20 |
21 |
public string Name |
22 |
{ |
23 |
get { return _name; } |
24 |
set { _name = value; } |
25 |
} |
26 |
} |
改为
01 |
public abstract class Emplayee |
02 |
{ |
03 |
private string _name; |
04 |
05 |
public string Name |
06 |
{ |
07 |
get { return _name; } |
08 |
set { _name = value; } |
09 |
} |
10 |
} |
11 |
12 |
public class Salesman : Emplayee |
13 |
{ |
14 |
15 |
} |
16 |
17 |
public class Engineer : Emplayee |
18 |
{ |
19 |
20 |
} |
三、Pull Up Method(函数上移)
动机(Motivation)
有些函数,在各个subclass中产生完全相同的结果。将该函数移至superclass。
示例
01 |
public abstract class Emplayee |
02 |
{ |
03 |
04 |
} |
05 |
06 |
public class Salesman : Emplayee |
07 |
{ |
08 |
public string GetName() |
09 |
{ |
10 |
return "spring yang" ; |
11 |
} |
12 |
} |
13 |
14 |
public class Engineer : Emplayee |
15 |
{ |
16 |
public string GetName() |
17 |
{ |
18 |
return "spring yang" ; |
19 |
} |
20 |
} |
改为
01 |
public abstract class Emplayee |
02 |
{ |
03 |
public string GetName() |
04 |
{ |
05 |
return "spring yang" ; |
06 |
} |
07 |
} |
08 |
09 |
public class Salesman : Emplayee |
10 |
{ |
11 |
} |
12 |
13 |
public class Engineer : Emplayee |
14 |
{ |
15 |
} |
四、Pull Up Constructor Body(构造函数本体上移)
动机(Motivation)
在各个subclass中拥有一些构造函数,它们的本体代码几乎一致,在base中新建一个构造函数,并在subclass构造函数中调用它。
示例
01 |
public abstract class Emplayee |
02 |
{ |
03 |
private string _ID; |
04 |
private string _name; |
05 |
06 |
public string ID |
07 |
{ |
08 |
get { return _ID; } |
09 |
set { _ID = value; } |
10 |
} |
11 |
12 |
public string Name |
13 |
{ |
14 |
get { return _name; } |
15 |
set { _name = value; } |
16 |
} |
17 |
} |
18 |
19 |
public class Salesman : Emplayee |
20 |
{ |
21 |
public Salesman( string id, string name) |
22 |
{ |
23 |
ID = id; |
24 |
Name = name; |
25 |
} |
26 |
} |
改为
01 |
public abstract class Emplayee |
02 |
{ |
03 |
private string _ID; |
04 |
private string _name; |
05 |
06 |
public string ID |
07 |
{ |
08 |
get { return _ID; } |
09 |
set { _ID = value; } |
10 |
} |
11 |
12 |
public string Name |
13 |
{ |
14 |
get { return _name; } |
15 |
set { _name = value; } |
16 |
} |
17 |
18 |
public Emplayee( string id, string name) |
19 |
{ |
20 |
_ID = id; |
21 |
_name = name; |
22 |
} |
23 |
} |
24 |
25 |
public class Salesman : Emplayee |
26 |
{ |
27 |
public Salesman( string id, string name): base (id,name) |
28 |
{ |
29 |
} |
30 |
} |
五、Push Down Method(函数下移)
动机(Motivation)
superclass中的某个函数只与部分(而非全部)subclasses有关。将这个函数移到相关的那些subclasses去。
示例
01 |
public abstract class Emplayee |
02 |
{ |
03 |
public double GetQuota() |
04 |
{ |
05 |
return 0; |
06 |
} |
07 |
} |
08 |
09 |
public class Salesman : Emplayee |
10 |
{ |
11 |
12 |
} |
13 |
14 |
public class Engineer : Emplayee |
15 |
{ |
16 |
17 |
} |
改为
01 |
public abstract class Emplayee |
02 |
{ |
03 |
04 |
} |
05 |
06 |
public class Salesman : Emplayee |
07 |
{ |
08 |
public double GetQuota() |
09 |
{ |
10 |
return 0; |
11 |
} |
12 |
} |
13 |
14 |
public class Engineer : Emplayee |
15 |
{ |
16 |
17 |
} |
六、Push Down Field(值域下移)
动机(Motivation)
superclass中的某个值域只被部分(而非全部)subclasses用到。将这个值域移到需要它的那些subclasses去。
示例
01 |
public abstract class Emplayee |
02 |
{ |
03 |
private double _quota; |
04 |
public double Quota |
05 |
{ |
06 |
get { return _quota; } |
07 |
set { _quota = value; } |
08 |
} |
09 |
} |
10 |
11 |
public class Salesman : Emplayee |
12 |
{ |
13 |
14 |
} |
15 |
16 |
public class Engineer : Emplayee |
17 |
{ |
18 |
19 |
} |
改为
01 |
public abstract class Emplayee |
02 |
{ |
03 |
04 |
} |
05 |
06 |
public class Salesman : Emplayee |
07 |
{ |
08 |
private double _quota; |
09 |
public double Quota |
10 |
{ |
11 |
get { return _quota; } |
12 |
set { _quota = value; } |
13 |
} |
14 |
} |
15 |
16 |
public class Engineer : Emplayee |
17 |
{ |
18 |
19 |
} |
七、Extract Subclass(提炼子类)
动机(Motivation)
class中的某些特性(features)只被某些(而非全部)实体(instances)用到,新建一个subclass,将上面所说的那一部分特性移到subclass中。
示例
01 |
public class JobItem |
02 |
{ |
03 |
public double GetTotalPrice() |
04 |
{ |
05 |
return 1000; |
06 |
} |
07 |
08 |
public double GetUnitPrice() |
09 |
{ |
10 |
return 10; |
11 |
} |
12 |
13 |
public string GetEmployee() |
14 |
{ |
15 |
return 100; |
16 |
} |
17 |
} |
改为
01 |
public class JobItem:BaseItem |
02 |
{ |
03 |
public double GetTotalPrice() |
04 |
{ |
05 |
return 1000; |
06 |
} |
07 |
08 |
} |
09 |
10 |
public class BaseItem |
11 |
{ |
12 |
public double GetUnitPrice() |
13 |
{ |
14 |
return 10; |
15 |
} |
16 |
} |
17 |
18 |
public class LaborItem:BaseItem |
19 |
{ |
20 |
public string GetEmployee() |
21 |
{ |
22 |
return 100; |
23 |
} |
24 |
} |
八、Extract Superclass(提炼超类)
动机(Motivation)
两个classes有相似特性(similar features)。为这两个classes建立一个superclass,将相同特性移至superclass。
示例
01 |
public class Department |
02 |
{ |
03 |
public double GetAnnualCost() |
04 |
{ |
05 |
return 1000; |
06 |
} |
07 |
08 |
public string GetName() |
09 |
{ |
10 |
return "spring yang" ; |
11 |
} |
12 |
13 |
public double GetHeadCount() |
14 |
{ |
15 |
return 100; |
16 |
} |
17 |
} |
18 |
19 |
public class Employee |
20 |
{ |
21 |
public double GetAnnualCost() |
22 |
{ |
23 |
return 1000; |
24 |
} |
25 |
26 |
public string GetName() |
27 |
{ |
28 |
return "spring yang" ; |
29 |
} |
30 |
31 |
public int GetID() |
32 |
{ |
33 |
return 1; |
34 |
} |
35 |
} |
改为
01 |
public class LaborItem:BaseItem |
02 |
{ |
03 |
public string GetEmployee() |
04 |
{ |
05 |
return 100; |
06 |
} |
07 |
} |
08 |
09 |
public class Department:Party |
10 |
{ |
11 |
public double GetHeadCount() |
12 |
{ |
13 |
return 100; |
14 |
} |
15 |
} |
16 |
17 |
public class Employee:Party |
18 |
{ |
19 |
public int GetID() |
20 |
{ |
21 |
return 1; |
22 |
} |
23 |
} |
24 |
25 |
public class Party |
26 |
{ |
27 |
public double GetAnnualCost() |
28 |
{ |
29 |
return 1000; |
30 |
} |
31 |
32 |
public string GetName() |
33 |
{ |
34 |
return "spring yang" ; |
35 |
} |
36 |
} |
九、Extract Interface(提炼接口)
动机(Motivation)
若干客户使用class接口中的同一子集;或者,两个classes的接口有部分相同。将相同的子集提炼到一个独立接口中。
示例
01 |
public class Employee |
02 |
{ |
03 |
public double GetRate() |
04 |
{ |
05 |
return 1; |
06 |
} |
07 |
08 |
public bool HasSpecialSkill() |
09 |
{ |
10 |
return true ; |
11 |
} |
12 |
13 |
public string GetName() |
14 |
{ |
15 |
return "spring yang" ; |
16 |
} |
17 |
18 |
public string GetDepartMent() |
19 |
{ |
20 |
return "Development" ; |
21 |
} |
22 |
} |
改为
01 |
public class Employee:Billable |
02 |
{ |
03 |
public double GetRate() |
04 |
{ |
05 |
return 1; |
06 |
} |
07 |
08 |
public bool HasSpecialSkill() |
09 |
{ |
10 |
return true ; |
11 |
} |
12 |
13 |
public string GetName() |
14 |
{ |
15 |
return "spring yang" ; |
16 |
} |
17 |
18 |
public string GetDepartMent() |
19 |
{ |
20 |
return "Development" ; |
21 |
} |
22 |
} |
23 |
24 |
public interface Billable |
25 |
{ |
26 |
double GetRate(); |
27 |
bool HasSpecialSkill(); |
28 |
} |
十、Collapse Hierarchy(折叠继承体系)
动机(Motivation)
superclass 和subclass之间无太大区别。将它们合为一体。
示例
01 |
public class Employee |
02 |
{ |
03 |
public string GetName() |
04 |
{ |
05 |
return "spring yang" ; |
06 |
} |
07 |
08 |
public string GetDepartMent() |
09 |
{ |
10 |
return "Development" ; |
11 |
} |
12 |
} |
13 |
14 |
public class Salesman |
15 |
{ |
16 |
public int GetID() |
17 |
{ |
18 |
return 1; |
19 |
} |
20 |
} |
改为
01 |
public class Employee |
02 |
{ |
03 |
public string GetName() |
04 |
{ |
05 |
return "spring yang" ; |
06 |
} |
07 |
08 |
public string GetDepartMent() |
09 |
{ |
10 |
return "Development" ; |
11 |
} |
12 |
13 |
public int GetID() |
14 |
{ |
15 |
return 1; |
16 |
} |
17 |
} |
步步为营 .NET 代码重构学习笔记系列
步步为营 .NET 代码重构学习笔记 二、提炼方法(Extract Method)
步步为营 .NET 代码重构学习笔记 三、内联方法(Inline Method)
步步为营 .NET 代码重构学习笔记 四、临时变量(Temporary Variable)
步步为营 .NET 代码重构学习笔记 五、分解函数和替换算法(Replace Method And Substitute Algorithm)