步步为营 .NET 代码重构学习笔记 十
一、Replace Type Code with Subclasses (以子类取代型别码)
动机(Motivation)
以一个subclass取代这个type code,如果面对的type code不会影响宿主类的行为,可以使用Replace Type Code with Class 来处理它们。但如果type code 会影响宿主类的行为,那么最好的办法就是借助多态(polymorphism)业处理 变化行为。
示例
01 |
public class Employee |
02 |
{ |
03 |
private int _type; |
04 |
public static int ENGINEER = 0; |
05 |
public static int SALEMAN = 1; |
06 |
public static int MANAGER = 2; |
07 |
08 |
public Employee( int type) |
09 |
{ |
10 |
_type = type; |
11 |
} |
12 |
} |
改为
01 |
public class Employee |
02 |
{ |
03 |
private int _type; |
04 |
public static int ENGINEER = 0; |
05 |
public static int SALEMAN = 1; |
06 |
public static int MANAGER = 2; |
07 |
08 |
public Employee( int type) |
09 |
{ |
10 |
_type = type; |
11 |
} |
12 |
13 |
public int Type |
14 |
{ |
15 |
get { return _type; } |
16 |
set { _type = value; } |
17 |
} |
18 |
19 |
20 |
} |
21 |
22 |
public class ENGINEER : Employee |
23 |
{ |
24 |
public int GetType() |
25 |
{ |
26 |
return Employee.ENGINEER; |
27 |
} |
28 |
} |
29 |
30 |
public class SALEMAN : Employee |
31 |
{ |
32 |
public int GetType() |
33 |
{ |
34 |
return Employee.SALEMAN; |
35 |
} |
36 |
} |
37 |
38 |
public class MANAGER : Employee |
39 |
{ |
40 |
public int GetType() |
41 |
{ |
42 |
return Employee.MANAGER; |
43 |
} |
44 |
} |
45 |
46 |
public class Factory:Employee |
47 |
{ |
48 |
public Employee Create( int type) |
49 |
{ |
50 |
switch (type) |
51 |
{ |
52 |
case ENGINEER: |
53 |
return new ENGINEER(); |
54 |
case SALEMAN: |
55 |
return new SALEMAN(); |
56 |
case MANAGER: |
57 |
return new MANAGER(); |
58 |
default : |
59 |
throw new ExecutionEngineException( "Incorrect type code value" ); |
60 |
} |
61 |
} |
62 |
} |
二、Replace Type Code with State/Strategy(以State/Strategy取代型别码)
动机(Motivation)
以State object(专门用来描述状态的对象)取代type code。
示例
01 |
public class Employee |
02 |
{ |
03 |
private int _type; |
04 |
public static int ENGINEER = 0; |
05 |
public static int SALEMAN = 1; |
06 |
public static int MANAGER = 2; |
07 |
08 |
public Employee( int type) |
09 |
{ |
10 |
_type = type; |
11 |
} |
12 |
13 |
public int Type |
14 |
{ |
15 |
get { return _type; } |
16 |
set { _type = value; } |
17 |
} |
18 |
19 |
public int PayAmount() |
20 |
{ |
21 |
switch (_type) |
22 |
{ |
23 |
case ENGINEER: |
24 |
return 100; |
25 |
case SALEMAN: |
26 |
return 1000; |
27 |
case MANAGER: |
28 |
return 10000; |
29 |
default : |
30 |
throw new ExecutionEngineException( "Incorrect type code value" ); |
31 |
} |
32 |
} |
33 |
34 |
} |
改为
01 |
public class Employee |
02 |
{ |
03 |
private int _type; |
04 |
public static int ENGINEER = 0; |
05 |
public static int SALEMAN = 1; |
06 |
public static int MANAGER = 2; |
07 |
08 |
public Employee( int type) |
09 |
{ |
10 |
_type = type; |
11 |
} |
12 |
13 |
public int Type |
14 |
{ |
15 |
get { return _type; } |
16 |
set { _type = value; } |
17 |
} |
18 |
19 |
public int PayAmount() |
20 |
{ |
21 |
EmployeeType employeeType; |
22 |
switch (_type) |
23 |
{ |
24 |
case ENGINEER: |
25 |
employeeType= new ENGINEER(); |
26 |
break ; |
27 |
case SALEMAN: |
28 |
employeeType= new SALEMAN(); |
29 |
break ; |
30 |
case MANAGER: |
31 |
employeeType = new MANAGER(); |
32 |
break ; |
33 |
default : |
34 |
throw new ExecutionEngineException( "Incorrect type code value" ); |
35 |
} |
36 |
return employeeType.GetType(); |
37 |
} |
38 |
39 |
} |
40 |
41 |
public class ENGINEER : EmployeeType |
42 |
{ |
43 |
public override int GetType() |
44 |
{ |
45 |
return 100; |
46 |
} |
47 |
} |
48 |
49 |
public class SALEMAN : EmployeeType |
50 |
{ |
51 |
public override int GetType() |
52 |
{ |
53 |
return 1000; |
54 |
} |
55 |
} |
56 |
57 |
public class MANAGER : EmployeeType |
58 |
{ |
59 |
public override int GetType() |
60 |
{ |
61 |
return 10000; |
62 |
} |
63 |
} |
64 |
65 |
public abstract class EmployeeType |
66 |
{ |
67 |
public abstract int GetType(); |
68 |
69 |
} |
三、Replace Subclass with Fields(以值域取代子类)
动机(Motivation)
修改这些函数,使它们返回superclass中的某个(新增值域,然后销毁subclasses)
示例
01 |
public abstract class Person |
02 |
{ |
03 |
public abstract bool IsMale(); |
04 |
public abstract string GetCode(); |
05 |
06 |
public Person CreateMale() |
07 |
{ |
08 |
return new Male(); |
09 |
} |
10 |
11 |
public Person CreateFemale() |
12 |
{ |
13 |
return new Female(); |
14 |
} |
15 |
} |
16 |
17 |
public class Male : Person |
18 |
{ |
19 |
20 |
public override bool IsMale() |
21 |
{ |
22 |
return true ; |
23 |
} |
24 |
25 |
public override string GetCode() |
26 |
{ |
27 |
return "M" ; |
28 |
} |
29 |
} |
30 |
31 |
public class Female : Person |
32 |
{ |
33 |
34 |
public override bool IsMale() |
35 |
{ |
36 |
return false ; |
37 |
} |
38 |
39 |
public override string GetCode() |
40 |
{ |
41 |
return "F" ; |
42 |
} |
43 |
} |
改为
01 |
public class Person |
02 |
{ |
03 |
private bool _IsMale; |
04 |
private string _Code; |
05 |
06 |
public bool IsMale |
07 |
{ |
08 |
get { return _IsMale; } |
09 |
set { _IsMale = value; } |
10 |
} |
11 |
12 |
public string Code |
13 |
{ |
14 |
get { return _Code; } |
15 |
set { _Code = value; } |
16 |
} |
17 |
public Person( bool isMale, string code) |
18 |
{ |
19 |
this ._IsMale = isMale; |
20 |
this ._Code = code; |
21 |
} |
22 |
} |
23 |
24 |
public class Male : Person |
25 |
{ |
26 |
27 |
public Male() |
28 |
: base ( true , "M" ) |
29 |
{ } |
30 |
} |
31 |
32 |
public class Female : Person |
33 |
{ |
34 |
public Female() |
35 |
: base ( false , "F" ) |
36 |
{ } |
37 |
} |
四、Decompose Conditional(分解条件式)
动机(Motivation)
从if、then、else三个段落中分别提炼出独立函数。
示例
1 |
if (date<SUMMER_START||date>SUMMER_BND) |
2 |
charge=quantity*_winterRate+_winterServiceCharge; |
3 |
else |
4 |
charge=quantity*_summerRate; |
改为
1 |
if (notSummer(date)) |
2 |
charge=winterCharge(quantity); |
3 |
else |
4 |
charge=summerCharge(quantity); |
五、Consolidate Conditional Expression(合并条件式)
动机(Motivation)
将很多条件合并成一个条件式,并将这个条件式提炼成为一个独立函数。
示例
1 |
public double DisabilityAmount() |
2 |
{ |
3 |
if (_seniority < 2) return 0; |
4 |
if (_monthsDisabled > 12) return 0; |
5 |
if (_isPartTime) return 0; |
6 |
return 1; |
7 |
} |
改为
1 |
public double DisabilityAmount() |
2 |
{ |
3 |
if (IsNotBligableForDisability()) return 0; |
4 |
return 1; |
5 |
} |
六、Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
动机(Motivation)
将重复代码搬移到条件式之外。
示例
01 |
if (isSpecialDeal()) |
02 |
{ |
03 |
total = price * 0.95; |
04 |
sendMail(); |
05 |
} |
06 |
else |
07 |
{ |
08 |
total = price * 0.98; |
09 |
sendMail(); |
10 |
} |
改为
1 |
if (isSpecialDeal()) |
2 |
total = price * 0.95; |
3 |
else |
4 |
total = price * 0.98; |
5 |
6 |
sendMail(); |
http://u.huoban001.com/space.php