一、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(); |