概述
第七章:在对象之间搬移特性
- 1、Move Method(搬移函数)
- 2、Move Field(搬移字段)
- 3、Extract Class(提炼类)
- 4、Inline Class(将类内联化)
- 5、Hide Delegate(隐藏“委托关系”)
- 6、Remove Middle Man(移除中间人)
- 7、Introduce Foreign Method(引入外加函数)
- 8、Introduce Local Extension(引入本地扩展)
1、Move Method(搬移函数)
在程序中有个函数与其所驻类之外另一个类有更多的调用、被调用关系,
那么在另一类中建立一个有着类似行为的新函数,在将旧函数变成一个单纯的委托,或者将旧函数移除
public class Ranking{
int baseScore = 10;
private int GetStudentIntegral(){
if(student.TimeOut()){
return student.Score* 0.9f;
}
else return baseScore + student.Result;
}
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓等价于↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
public class Ranking{
int baseScore = 10;
private int GetStudentIntegral(){
return student.GetIntegral(baseScore);
}
}
public class Student{
public int GetIntegral( int baseScore){
if(TimeOut()){
return Score* 0.9f;
}
else return baseScore + Score;
}
}
- 搬移函数是解耦常用的方法
2、Move Field(搬移字段)
某个字段被所驻类之外的另一个类更多的用到,在另一个类新建一个字段,修改原字段的所有引用。
示例:略
- 如果字段是频繁被访问的,那么先使用Self Encapsulate Field(自封装字段)、Encapsulate Field(封装字段)
3、Extract Class(提炼类)
一个类做了两个或更多类做的事,建立相应的新类,将相关的字段和函数从旧类版移动新类。
示例:略
- 使用该方法的时候是不可避免的使用移动函数、移动字段
- 修改对搬移特性的引用点
4、Inline Class(将类内联化)
某个类没有做太多事情,将这个类的所有特性搬移到另一个类中,然后移除源类。
- 与提炼类正好相反,但同样也要使用移动函数、移动字段
5、Hide Delegate(隐藏“委托关系”)
通过一个委托调用另一个对象。
在服务类上建立所需的所有函数,用以隐藏委托关系。
//工人person
部分department
public class Person{
private Department department;
public Department GetDepartment(){
return department;
}
public void SetDepartment(Department _department){
department = _department;
}
}
public class Department(){
private Person manager;//经理
public Department(Person _person){
manager = _person;
}
public Person GetManager(){
return manager;
}
}
如果客服想知道某人的经理是谁,那么他就得先取得Department对象:
manager = person.GetDepartment().GetManager();
这样就对客户暴露了Department的工作原理,如果要对客户隐藏Department,可以减少耦合:在Person中建立一个简单的委托函数
public Person GetManager(){
return department.GetManager();
}
那么获取经理的方式就改为:
manager = person.GetManager();
6、Remove Middle Man(移除中间人)
某个类做了过多的简单的委托动作。
直接调用委托类。
例子:隐藏“委托关系”前后代码前后颠倒即可。
- 与**隐藏“委托关系”**相反。
- 过多的中间层会增加代码维护的为难
- 本方法会减少中间层的使用,某些情况下会产生将类内联化现象。
7、Introduce Foreign Method(引入外加函数)
当你为一个类增加一个函数,但你无法修改这个类的时候。在外部调用类中新建一个函数,并以参数的形式传入该类对象。
Date newStart = new Date(previous.GetYear(),previous.GetMonth(),previous.GetData());
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓等价于↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
Data newStart = new Data(previous.GetYear(),previous.GetMonth(),previous.GetData());
private Date NextDate(Date arg){
return new Data(arg.GetYear(),arg.GetMonth(),arg.GetData());
}
新加的这个函数就是Date的一个外加函数。
- 需要增加的函数少时(一两个)用外加函数,如果多时就用下面的方法引入本地扩展
PS:个人认为外加函数就是对接口的一个扩展,以用来兼容原始接口的。
8、Introduce Local Extension(引入本地扩展)
当你为一个类增加一个函数,但你无法修改这个类的时候。
新建一个类,使他包含这些额外的函数,让这个类成为源类的*子类*或者*基类*
- 在新类选择作为子类和包装类时,首选子类(工作量小),如果源类的原始数据允许被修改,那么就必须使用包装类
作为 子类:
public class DateSub:Date{
//处理构造函数的时候注意下
//添加新特性
private Date NextDate(){
return new Data(GetYear(),GetMonth(),GetData());
}
}
作为 包装类:
public class DateWrap{
private Date original;
public DateWrap(Date arg){
original = arg;
}
//为原始类所有函数提供委托函数,例如:
public int GetYear(){
return original.GetYear();
}
...
//添加新特性
private Date NextDate(){
return new Data(GetYear(),GetMonth(),GetData());
}
}
- 此外还需要处理源类的外部调用函数
上一章:读《重构-改善既有代码的设计》第六章:重新组织函数
下一章:读《重构-改善既有代码的设计》第七章:在对象之间搬移特性
最后
以上就是谦让小海豚为你收集整理的读《重构-改善既有代码的设计》第七章:在对象之间搬移特性的全部内容,希望文章能够帮你解决读《重构-改善既有代码的设计》第七章:在对象之间搬移特性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复