这一次重新组织数据,我还没看之前,感觉并不是主动进行重构,二是为了后续重构提供便利。

自封装字段(Self Encapsulate Field)

其实很多人觉得这个有点多余,scala 语言专门提供了字段访问的方式,隐藏了get set方法。 如果直接访问字段,可能会让耦合关系变得笨拙。当你遇到问题的时候,例如子类可能需要覆盖get函数等,发现通过访问字段方式可能更合适。

以对象取代数据 (Replace Data Value with Object)

对象取代数据,似乎与我们大数据处理是相反的。不过这样可能会存在性能问题,但是大部分情况不用担心。

Change Value to Reference(将值对象改为引用对象)

这个提到的问题有点类似单例模式,我要保证每个访问点返回同一个对象:

class Order...
public Order(String customerName){
	_customer = new Customer(customerName);
}
public void setCustomer(String customerName){
	_customer = new Customer(customerName);
}
public String getCustomerName(){
	return _customer.getName();
}

这个每次 setCustomer 其实都会new 新的。这里可以结合工厂模式,保证每次都是一样的。例如准备一个 HashMap。

Change Reference to Value(将引用对象改为值对象)

如果你的饮用对象很小,而且不可变。例如只需要一个 userid,就没必要new 一个 user。这里的不可变不是对象不可变,而是不能对他进行修改。也就是没有 setting method

Replace Array with Object(以对象取代数组)

这个应该属于比较古老的代码,现在我没有遇到过。

Duplicate Observed Data(复制“被监视数据”)

这个属于 GUI 的东西,后续再看。

8.7 Change Unidirectional Association to Bidirectional (将单向关联改为双向关联)

这种手法不太推荐,操作有一定难度。 如果你有自己实现过红黑树、B树的代码,应该有所体验。如果子节点不保存到父节点的指针,那么很多代码操作就会比较复杂。这时候会用双向指针。

参考 HashMap的源码,父节点有到两个子节点的指针,子节点也有到父节点的指针。

1.如果两者都是引用对象,而其间的关联是“一对多”关系,那么就由“拥有单一引用”的那一方承担“控制者”角色。以本例而言,如果一个客户可拥有多份定单,那么就由Order类(定单)来控制关联关系。 2.如果某个对象是组成另一对象的部件,那么由后者负责控制关联关系。 3.如果两者都是引用对象s,而其间的关联是“多对多”关系,那么随便其中哪个对象来控制关联关系,都无所谓。

双向改为单向

这和上一步反过来,这个步骤是很麻烦的。

字面常量取代魔法数

这个实际上就是我们所说的常量提取。但是问题是提取出来的常量放在那里?专门定义类,还是放在出现最多的类里。

封装字段。

类似 自封装字段。

封装集合

目的是操作集合字段和其他字段不能和一般字段一样,因为集合可以添加删除字段。

以数据类取代记录

类似 将值对象改为引用对象

Replace Type Code with Class(以类取代类型码)

类取代类型码可以方便编译器检查错误。

Replace Type Code with Subclasses(以子类取代类型码)

如果类型码有对应的判断条件,然后有不同的操作类型,这时候通过子类取代,然后用多态的方式取代判断。

8.15 Replace Type Code with State/Strategy (以State/Strategy取代类型码)

Replace Type Code with Subclasses(以子类取代类型码)很强大,但是以下两种情况你不能那么做:(1)类型码值在对象创建之后发生了改变;(2)由于某些原因,类型码宿主类已经有了子类。如果你恰好面临这两种情况之一, 就需要使用Replace Type Code with State/Strategy (227)。

Replace Subclass with Fields(以字段取代子类)

这个和上面的操作是相反的,如果类过于简单,只有某个常量数据,就可以取代掉。