《重构--改善既有代码的设计》--处理概括关系(11)
来源:互联网 发布:慢性牙周炎 知乎 编辑:程序博客网 时间:2024/06/06 00:37
一、Pull Up Field(字段上移)
两个子类拥有相同的字段。将该字段移至超类。
二、Pull Up Method(函数上移)
有些函数,在各个子类中产生完全相同的结果。将该函数移至父类。
1、检查待提升函数,确定它们是完全一致的。
2、如果特提升函数名不同,修改与父类相同的函数名。
3、在父类新建一个函数,将待提升的函数代码复制到到新函数中。
4、编译。
5、移除子类中的函数。
6、编译、测试。
7、逐一移除子类中的函数,直到只剩下父类中的函数。
8、编译、测试。
重构后:
三、Pull Up Constructor Body(构造函数本体上移)
你在各个子类中拥有一些构造函数,它们的本体几乎完全一致。在父类中新建一个构造函数,并在子类构造函数中调用它。
1、在父类定义一个构造函数。
2、将子类共同代码搬移到父类中构造函数中。
3、将子类构造函数共同代码删除,改用父类中的构造函数。
4、编译、测试。
class Employee { protected string _name; protected string _id; public Employee(string name, string id) { _name = name; _id = id; } }
class Manager : Employee { private int _grade; public Manager(string name, string id, int grade) { _name = name; _id = id; _grade = grade; } }
重构后:
class Manager : Employee { private int _grade; public Manager(string name, string id, int grade) :base(name,id) { _grade = grade; } }
四、Push Down Method(函数下移)
父类中的某个函数只与部分(而非全部)子类有关。将这个函数移到相关的那些子类去。
五、Push Down Field(字段下移)
父类中某个字段只被部分(而非全部)子类用到。将这个字段移到需要它的那些子类中。
六、Extract Subclass(提炼子类)
类中的某些特性只被某些(而非全部)实例用到。新建一个子类,将上面所说的那一部分特性移到子类中。
1、为源类定义一个新的子类。
2、为这个新的子类提供构造函数。
3、找出父类的构造函数,如果是需要子类的构造函数,请替换之。
4、逐一使用Push Down Method和Push Down Field将源类的特性移到子类。
5、编译、测试。
class JobItem { private int _unitPrice; private int _quantity; private bool _isLabor; private Employee _employee; public JobItem(int unitPrice, int quantity, bool isLabor, Employee employee) { _unitPrice = unitPrice; _quantity = quantity; _isLabor = isLabor; _employee = employee; } public int GetTotalPrice() { return GetUnitPrice() * _quantity; } public int GetUnitPrice() { return (_isLabor) ? _employee.GetRate() : _unitPrice; } public int Quantity { get { return _quantity; } } public Employee Employee { get { return _employee; } } }
class Employee { protected int _rate; public Employee(int rate) { _rate = rate; } public int GetRate() { return _rate; } }
class Program { static void Main(string[] args) { Employee kent = new Employee(3600); JobItem j1 = new JobItem(0, 5, true, kent); } }
创建一个子类,重构后:
class JobItem { private int _unitPrice; private int _quantity; private bool _isLabor; protected Employee _employee; protected JobItem(int unitPrice, int quantity, bool isLabor) { _unitPrice = unitPrice; _quantity = quantity; _isLabor = isLabor; } public JobItem(int unitPrice, int quantity) : this(unitPrice, quantity, false) { } public int GetTotalPrice() { return GetUnitPrice() * _quantity; } public virtual int GetUnitPrice() { return _unitPrice; } public int Quantity { get { return _quantity; } } protected virtual bool IsLabor() { return false; } }
class LaborItem:JobItem { public LaborItem(int unitPrice, int quantity, bool isLabor) : base(unitPrice, quantity, isLabor) { } public LaborItem(int quantity, Employee employee) : base(0, quantity, true) { _employee = employee; } public Employee Employee { get { return _employee; } } protected override bool IsLabor() { return true; } public override int GetUnitPrice() { return _employee.GetRate(); } }
客户端:
class Program { static void Main(string[] args) { Employee kent = new Employee(3600); JobItem j1 = new LaborItem(10, 5, true); JobItem j2 = new JobItem(10, 15); } }
七、Extract Superclass(提炼超类)
两个类有相似特性。为这两个类建立一个父类,将相同特性移至父类。
1、建立一个抽象父类。
2、运用Pull Up Field,Pull Up Method,Pull Up Constructor Boday逐一将子类共同元素上移到父类。
3、编译、测试。
八、Extract Interface(提炼接口)
若干客户使用类接口中的同一子集,或者两个类的接口有部分相同。将相同的子集提炼到一个独立接口中。
1、新建一个接口。
2、在接口中声明待提炼类的共通操作。
3、让相关的类实现其接口。
4、调整客户端的类型声明,令其使用该接口。
class Employee { private int _rate; private bool _isSpecialSkill; Employee(int rate, bool isSpecialSkill) { _rate = rate; _isSpecialSkill = isSpecialSkill; } public int GetRate() { return _rate; } public bool HasSpecialSkill() { return _isSpecialSkill; } }
class TimeSheet { double Charge(Employee employee, int days) { int basic = employee.GetRate() * days; return (employee.HasSpecialSkill()) ? (basic * 1.05) : basic; } }
重构后:
interface IBillable { int GetRate(); bool HasSpecialSkill(); }
class TimeSheet { double Charge(<span style="color:#ff0000;">IBillable </span>employee, int days) { int basic = employee.GetRate() * days; return (employee.HasSpecialSkill()) ? (basic * 1.05) : basic; } }
九、Collapse Hierarchy(折叠继承体系)
父类与子类之间无太大区别,将它们合为一体。
1、选择你想移除的类:父类或子类。
2、使用Pull Up Field,Pull Up Method或Push Dwon Field,Push Down Method,把想移除的行为和属性搬移到另一个类中。
3、编译、测试。
4、调整原类的引用点,改为新类的引用。
5、移除源空类。
6、编译、测试。
十、Form Template Method(塑造模板函数)
你有一些子类,其中相应的函数以相同的顺序执行类的操作,但各个操作的细节上有所不同。将这些操作分别放进独立函数中,并保持它们都有相同的签名,于是原函数也就变得相同了。然后将原函数上移至父类。
1、在各个子类中分解目标函数,使分解后的各个函数不完全相同。
2、运用Pull Up Method将各个子类完全相同的函数上移父类。
3、对于那些完全不同的函数,实施Rename Method,使这些函数的签名完全相同。
4、编译、测试。
5、运用Pull Up Method将所有函数逐一上移到父类,并声明为抽象函数。
6、编译、测试。
7、移除子类中的原函数,编译、测试。
重构后:
十一、Replace Inheritance with Delegation(以委托取代继承)
某个子类只使用父类接口中的一部分,或是根本不需要继承而来的数据。在子类中新建一个字段用以保存父类,调整子类函数,令它改而委托父类,然后去掉两者之间的继承关系。
1、在子类型新建一个字段,引用父类的一个实例。
2、修改子类所有函数,让它们不使用父类,转而使用字段。
3、编译、测试。
4、去除继承关系。
5、编译、测试。
十二、Replace Delegation with Inheritance(以继承取代委托)
你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数。让委托类继承受托类。
1、让委托端成为受托端的子类。
2、编译。
3、将受托字段设为该字段所处对象本身。
4、去掉简单的委托函数。
5、编译、测试。
6、把调用委托的代码改为对象本身。
7、移除受托字段。
class Person { private string _name; public string Name { get { return _name; } set { _name = value; } } public string GetLastName() { return _name.SubString(_name.LastIndexOf(' ') +1); } }
class Employee { Person _person = new Person(); public override string ToString() { return "Emp:" + _person.GetLastName(); } }
重构后:
class Employee : Person { public override string ToString() { return "Emp:" + GetLastName(); } }
- 重构改善既有代码的设计-处理概括关系
- 《重构--改善既有代码的设计》--处理概括关系(11)
- 《重构改善既有代码的设计》之重构列表--处理概括关系(一)
- 《重构改善既有代码的设计》之重构列表--处理概括关系(二)
- 《重构改善既有代码的设计》之重构列表--处理概括关系(三)
- 重构-改善既有代码的设计:处理概括关系 (九)
- 重构-改善既有代码的设计:处理概括关系 (九)
- 《重构-改善既有代码的设计》概括
- 重构-改善既有代码的设计
- 重构-改善既有代码的设计
- 重构-改善既有代码的设计
- 重构-改善既有代码的设计
- 重构:改善既有代码的设计
- 重构--改善既有代码的设计
- 重构-改善既有代码的设计
- 重构-改善既有代码的设计
- 重构-改善既有代码的设计+
- 重构--改善既有代码的设计
- Java 内存管理
- 运行百度地图demo时出现XML file line #6: Error inflating class com.baidu.mapapi.map.MapView的错误
- android 剪裁图片
- datanode无法启动
- BeeFramework框架学习之二(自定义提示框 照相机的实现)
- 《重构--改善既有代码的设计》--处理概括关系(11)
- Java基础——IO流(二)
- Linux配置文件系统路径
- 树形结构 数据组织方式
- 素材库亮相CityMaker7.0,轻松解决“烦人”的模型管理问题
- java的循环引用
- SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束。
- oracle PL/SQL
- 字符全排列