重构 - 组织数据
2016-03-09 10:45 yoogo 阅读(216) 评论(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
问题
各个子类的区别仅仅是某个字段的值不同。