标签:classes 策略 出现 群集 符号 dup 原因 magic 特性
自封装值域 就是 getter and setter,这就没啥好说的了。
比如:不用字符串表示电话号码,而用一个电话号码的类表示。
好处:更容易扩展,比如:以后需要一个函数来提取号码中的区号时,就可以直接写在这个类里面了。
引用对象可以是指针、引用、下标等。
好处:省空间,比较简单。
缺点:不能局部修改。
使用场景:一个数组容纳了数种不同对象。
这种特定场景的,不再多看了。
业务分层后,数据也应该分层,复制一份到下层。
但分层后的数据如何同步?需要通过观察者模式/事件监昕器
典型场景:前端数据变化通知后端。
两个classes都需要使用对方特性,但其间只有一条单向连接(one-way link)。
添加一个反向指针,并使修改函数(modifiers)能够同时更新两条连接。
目的:减少访问成本。
两个鄉之间有双向关联,但其中一个class如今不再需要另一个class的特性。
去除不必要的关联(association)。
目的:减少维护成本、复杂度。
目的:
1、只修改一处。2、含义明确。
就是改public 为 setter
描述:有个函数(method)返回一个群集(collection)。 让这个函数返回该群集的一个只读映件(read-only view),并在这个class中提供「添加/移除」(add/remove)群集元素的函数。
原因:会对用户暴露过多「对象内部数据结构」的信息。
本质上就是为群集做了一个委托。
目的:只有通过类提供的方法,才能修改群集。
实际上,Array就是这么做的,你是无法直接访问其中的数组datas的,而是要通过Array的add,remove等方法才能操作data。
这里的Record指的是Struct
识别码是啥?
public static final int O = 0;
public static final int A = 1;
public static final int B = 2;
public static final int AB = 3;
现在有枚举了,用枚举替代。
这就是解决switch问题的那个基本的重构方法。
好处是,可以消除多处的switch,只有初始化时还保留了switch。
解决switch的另一手段:状态模式/策略模式。
描述:
你的各个subclasses 的惟一差别只在「返回常量数据」的函数身上。
修改这些函数,使它们返回superclass 中的某个(新增)值域,然后销毁subclasses 。
原因:不必要使用子类的地方,去掉子类,更简单。
举例:
如果男人类和女人类的区别只是获取性别函数返回不同的值,那就只需要人类,性别做为一个final属性。
本章之中,我将讨论数个「能让你更轻松运用数据」的重构手法。
Replace Data Value with Object 让你可以将「哑」数据(dumb data)变成会说话的对象(articulate objects)。 如果你发现程序中有太多地方需要这一类对象,你也可以使用Change Value to Reference 将它们变成reference object。
对象之间的关联(links)可以单向,也可以双向。单向关联比较简单,但有时为了支持一项新功能,你需要以Change Unidirectional Association to Bidirectional 将它变成双向关联。Change Bidirectional Association to Unidirectional 则恰恰相反:如果你发现不再需要双向关联,可以使用这项重构将它变成单向关联。
我常常遇到这样的情况:GUI classes竟然去处理不该它们处理的业务逻辑(business logic)。为了把这些处理业务逻辑的行为移到合适的domain class去,你需要在domain class中保存这些逻辑的相关数据,并运用 Duplicate Observed Data 提供对GUI的支持。一般来说,我不喜欢重复的数据,但这是一个例外,因为这里的重复数据通常是不可避免的。
面向对象编程(OOP)的关键原则之一就是封装。如果一个class暴露了任何public数据,你就应该使用Encapsulate Field 将它高雅而正派地包装起来。如果被暴露的数据是个群集(collection),你就应该使用Encapsulate Collection 因为群集有其特殊协议。如果一整笔记录(record)都被裸露在外,你就应该使用 Replace Record with Data Class。
需要特别对待的一种数据是type code〔型别码):这是一种特殊数值,用来指出 「与实体所属之型别相关的某些东西」。Type code通常以枚举(enumeration)形式出现,并且通常以static final整数实现之。如果这些type code用来表现某种信息,并且不会改变所属class的行为,你可以运用 Replace Type Code with Class 将它们替换掉,这项重构会为你提供更好的型别检查,以及一个更好的平台,使你可以在未来更方便地将相关行为添加进去。另一方面,如果class的行为受到type code的影响,你就应该尽可能使用Replace Type Code with Subclasses。如果做不到,就只好使用更复杂(同时也更灵活)的 Replace Type Code with State/Strategy。
这章是基于面向对象思想的一些重构手段,由于本书写于2001年,当年java还是1.1-1.2,面向对象也不是很流行,所以作者的有些方法太过老旧了,有些方法现在已经是被认为理所当然的方法了。
面向对象的思想:继承、封装、多态。
重构方法:
1、封装数据: Self Encapsulate Field(自封装值域)/Encapsulate Field(封装值域)
2、魔鬼数字/枚举:Replace Magic Number with Symbolic Constant(以符号常量/字面常量取代魔法数)/Replace Type Code with Class(以类取代型别码)
3、尽量用对象,替代数据值/struct/群集:Change Value to Reference(将实值对象改为引用对象)/Replace Record with Data Class(以数据类取代记录)/ Encapsulate Collection(封装群集)
4、按需双向依赖:Change Unidirectional Association to Bidirectional(将单向关联改为双向)/Change Bidirectional Association to Unidirectional(将双向关联改为单向)
5、switch破除大法:子类/策略模式/状态模式:Replace Type Code with Class(以类取代型别码)/Replace Type Code with Subclasses(以子类取代型别码)/Replace Type Code with State/Strategy(以State/strategy 取代型别码) 6、避免过度使用子类。Replace Subclass with Fields(以值域取代子类)
7、数据分层。Duplicate Observed Data(复制「被监视数据」)
【重构.改善既有代码的设计】8、重新组织数据(更优雅的面向对象)
标签:classes 策略 出现 群集 符号 dup 原因 magic 特性
原文地址:https://www.cnblogs.com/aoyihuashao/p/10384482.html