步步为营 .NET 代码重构学习笔记系列
一、Replace Type Code with Subclasses (以子类取代型别码)
动机(Motivation)
以一个subclass取代这个type code,如果面对的type code不会影响宿主类的行为,可以使用Replace Type Code with Class 来处理它们。但如果type code 会影响宿主类的行为,那么最好的办法就是借助多态(polymorphism)业处理 变化行为。
示例
public class Employee { private int _type; public static int ENGINEER = 0; public static int SALEMAN = 1; public static int MANAGER = 2; public Employee(int type) { _type = type; } }
改为
public class Employee { private int _type; public static int ENGINEER = 0; public static int SALEMAN = 1; public static int MANAGER = 2; public Employee(int type) { _type = type; } public int Type { get { return _type; } set { _type = value; } } } public class ENGINEER : Employee { public int GetType() { return Employee.ENGINEER; } } public class SALEMAN : Employee { public int GetType() { return Employee.SALEMAN; } } public class MANAGER : Employee { public int GetType() { return Employee.MANAGER; } } public class Factory:Employee { public Employee Create(int type) { switch (type) { case ENGINEER: return new ENGINEER(); case SALEMAN: return new SALEMAN(); case MANAGER: return new MANAGER(); default: throw new ExecutionEngineException("Incorrect type code value"); } } }
二、Replace Type Code with State/Strategy(以State/Strategy取代型别码)
动机(Motivation)
以State object(专门用来描述状态的对象)取代type code。
示例
public class Employee { private int _type; public static int ENGINEER = 0; public static int SALEMAN = 1; public static int MANAGER = 2; public Employee(int type) { _type = type; } public int Type { get { return _type; } set { _type = value; } } public int PayAmount() { switch (_type) { case ENGINEER: return 100; case SALEMAN: return 1000; case MANAGER: return 10000; default: throw new ExecutionEngineException("Incorrect type code value"); } } }
改为
public class Employee { private int _type; public static int ENGINEER = 0; public static int SALEMAN = 1; public static int MANAGER = 2; public Employee(int type) { _type = type; } public int Type { get { return _type; } set { _type = value; } } public int PayAmount() { EmployeeType employeeType; switch (_type) { case ENGINEER: employeeType= new ENGINEER(); break; case SALEMAN: employeeType=new SALEMAN(); break; case MANAGER: employeeType = new MANAGER(); break; default: throw new ExecutionEngineException("Incorrect type code value"); } return employeeType.GetType(); } } public class ENGINEER : EmployeeType { public override int GetType() { return 100; } } public class SALEMAN : EmployeeType { public override int GetType() { return 1000; } } public class MANAGER : EmployeeType { public override int GetType() { return 10000; } } public abstract class EmployeeType { public abstract int GetType(); }
三、Replace Subclass with Fields(以值域取代子类)
动机(Motivation)
修改这些函数,使它们返回superclass中的某个(新增值域,然后销毁subclasses)
示例
public abstract class Person { public abstract bool IsMale(); public abstract string GetCode(); public Person CreateMale() { return new Male(); } public Person CreateFemale() { return new Female(); } } public class Male : Person { public override bool IsMale() { return true; } public override string GetCode() { return "M"; } } public class Female : Person { public override bool IsMale() { return false; } public override string GetCode() { return "F"; } }
改为
public class Person { private bool _IsMale; private string _Code; public bool IsMale { get { return _IsMale; } set { _IsMale = value; } } public string Code { get { return _Code; } set { _Code = value; } } public Person(bool isMale, string code) { this._IsMale = isMale; this._Code = code; } } public class Male : Person { public Male() : base(true, "M") { } } public class Female : Person { public Female() : base(false, "F") { } }
四、Decompose Conditional(分解条件式)
动机(Motivation)
从if、then、else三个段落中分别提炼出独立函数。
示例
if(dateSUMMER_BND) charge=quantity*_winterRate+_winterServiceCharge;else charge=quantity*_summerRate;
改为
if(notSummer(date)) charge=winterCharge(quantity);else charge=summerCharge(quantity);
五、Consolidate Conditional Expression(合并条件式)
动机(Motivation)
将很多条件合并成一个条件式,并将这个条件式提炼成为一个独立函数。
示例
public double DisabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; return 1; }
改为
public double DisabilityAmount() { if (IsNotBligableForDisability()) return 0; return 1; }
六、Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
动机(Motivation)
将重复代码搬移到条件式之外。
示例
if (isSpecialDeal()) { total = price * 0.95; sendMail(); } else { total = price * 0.98; sendMail(); }
改为
if (isSpecialDeal()) total = price * 0.95; else total = price * 0.98; sendMail();