代码改变世界

重构 - 组织数据

2016-03-09 10:45  yoogo  阅读(214)  评论(0编辑  收藏  举报

 


自封装字段 Self Encapsulate Field

目标:即使访问自己的属性,也要通过 getter/setter ;

 

 


Replace Data Value with Object

目标:

替换值类型为对象, 是抽类的一个特例

 


Change Value to Reference

问题:

应该引用相同的对象,而不是每次都创建一个新的

解决:

单例模式

 


Change Reference to Value

问题:

被引用的对象很小,且不怎么会改变

解:

把引用对象变成值对象,也就是新生成实例。

 


Replace Array with Object

问题

用数据表达结构性的数据

把数据变成对象

why 

数组适合相同类型的数据

收益

用索引还是用有意义的名字标识一个数据

 


Duplicate Observed Data

问题

直接拿领域对象作为GUI 对象

分离这两种数据为两种类型,使用观察者模式同步数据。

why 

根据单一职责原则,这个类似同一个个变量多次赋值的道理一样。毕竟,GUI 逻辑的修改和 领域对象的修改是不一样的,不应该相互影响。 

收益

 


Change Unidirectional Association to Bidirectional

变单向关联为双向

注意要保持关系的一致性,保证同时设置两个方向的关系,而不能仅仅设置一个

 


Change Bidirectional Association to Unidirectional

问题

没必要的双向关联 - 一个对象并不访问另一个对象的成员

 

 


Replace Magic Number with Symbolic Constant

问题

在代码中直接使用一个值,此值有特殊含义。

把这个值赋值给一个常量,并给常量起个有描述性的名称。

 

 


Encapsulate Field

问题

字段具有 public 的scope . 

 

 


Encapsulate Collection

目标:

如果字段为集合类型,那就不应再使用getter/setter直接访问集合,而应使用 add/remove 等操作元素的方法

why 

直接把集合暴露给客户是危险的

收益

 


Replace Type Code with Class

问题

有表示类型的简单类型的字段,但这个字段并不用于条件语句,不影响程序的行为;

通常这个类型是 String 或 int , 无法在编译时验证什么值是合法的。

区分

如果这个字段使用在条件语句中,则考虑使用子类或策略模式

Java 1.5 之后的enum 这是解决这个问题的,如果不能使用 enum , 那就创建一个新的类,使用它的对象代表合法的取值。

 

重构方法:

1,把代表类型的那个int或string字段移动到新建的类中;并只允许在构造方法设置它。

2,在静态类中为每一个可能的取值都创建一个静态方法,在静态方法中构造这个类型的对象;

 


Replace Type Code with Subclasses

问题

有表示类型的简单类型的字段,这个字段影响程序的逻辑,也就是说不同的值会走不同的代码

为此字段的每个可能的取值创建当前类的一个子类,然后把与字段值相关的代码移动到相关的子类中,使用多态替代流程控制

why 

收益

单一职责-一个子类负责一种情况

开闭原则 - 加入一种新的情况只需添加一个新的子类,不用改现有的代码

不适合的情况

如果类的继承体系已经存在,受单亲继承的限制,你只能选择策略/状态模式

如果类型字段的值是动态可变的,那也最好选择策略/状态模式


Replace Type Code with State/Strategy

问题

有表示类型的简单类型的字段,这个字段影响程序的逻辑,但又不能使用创建子类的方法摆脱它

创建新的状态类来表示这个字段的类型,并把不同的逻辑移到这个状态类的不同子类中。

收益:

开闭原则

选择:

策略模式: 如果仅仅是分开不同的算法

状态模式: 如果不仅仅是选择不同的算法,还影响其他字段值或其他行为

 


Replace Subclass with Fields

问题

各个子类的区别仅仅是某个字段的值不同。