003-重新组织数据

重新组织数据

1. Self Encapsulate Field(自封装字段)

Q:你直接访问一个字段,但与字段之间的耦合关系逐渐变得笨拙

A:为这个字段建立取值/设值函数,并且只以这些函数来访问字段

间接访问变量的好处是,子类可以通过覆写一个函数而改变获取数据的途径;支持延迟初始化等。

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

Q:你有一个数据项,需要与其他数据和行为一起使用才有意义。

A:将数据项变为对象

业务一开始可能仅仅需要一个数据值,后续慢慢加入针对数据值的各种行为和关联数据,此时 Duplicate Code 和 Feature Envy 的坏味道就会逐渐暴露。

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

Q:你从一个类衍生出许多彼此相等的实例,希望将它们替换为同一个对象。

A:将这个值对象变成引用对象。

之所以需要将值对象改为引用对象,通常的考虑是一些重复的对象需要同步改动,更直接的例子就是单例对象。

引用对象应该由静态字典或者注册表对象来管理,应该考虑预先创建好还是动态创建,通常需要考虑使用工厂模式进行创建。

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

Q:你有一个引用对象,很小且不可变,而且不易管理。

A:将它变成一个值对象。

引用对象必须被以某种方式控制,你必须向其控制者请求适当的对象。它们可能造成内存区域之间错综复杂的关联。而值对象,特别是不可变的值对象,使你无需考虑同步问题。

可变的引用对象是不应该变为值对象的,因为那将意味着你需要考虑各个值对象之间数据同步的问题。

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

Q:你有一个数组,其中的元素各自代表不同的东西。

A:以对象替换数组。对于数组中的每一个元素,以一个字段来表示。

假如一个数组的元素根据其下标具备不同的含义和行为以及数据解释方式,则对象更适合表示这些数据。

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

Q:你有一些领域数据置身于 GUI 控件中,而领域函数需要访问这些数据。

A:将该数据复制到一个领域对象中,建立一个 Observer 模式,用以同步领域对象和 GUI 对象内的重复数据。

简单来说,“让数据归数据,让显示归显示”;而实现这一特性离不开观察者模式。

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

Q:两个类都需要使用对方的特性,但其间只有一条单向连接

A:添加一个反向指针,并使修改函数能够同时更新两条连接。

如何确定由谁控制双向关联关系:

  • 如果两者都是引用对象,且关联关系是“一对多”的关系,那么就由“拥有单一引用”的那一方承担“控制者”角色
  • 如果某个对象是组成另一个对象的部件,那么由后者负责控制关联关系
  • 如果两者是“多对多”的关系,由谁控制关联关系都无所谓

8. Change Bidirectional Association to Unidirectional

Q:两个类之间有双向关联,但其中一个类如今不再需要另一个类的特性。

A:去除不必要的关联。

维护双向连接增加了复杂度,且容易造成内存泄漏,增加模块间耦合。

9. Replace Magic Number with Symbolic Constant(以字面常量取代魔法数)

Q:你有一个字面数值,带有特别含义。

A:创造一个常量,根据其意义为它命名,并将上述的字面数值替换为这个常量。

10. Encapsulate Field(封装字段)

Q:你的类中存在一个 public 字段

A:将它声明为 private,并提供相应的访问函数。

11. Encapsulate Collection(封装集合)

Q:有个函数返回一个集合。

A:让这个函数返回该集合的一个只读副本,并在这个类中提供添加/移除集合元素的函数。

取值函数不应该返回集合自身,因为这样用户修改集合内容时集合拥有者将一无所知。

12. Replace Record with Data Class(以数据类取代记录)

Q:你需要面对传统编程环境中的记录结构。

A:为该记录创建一个“哑”数据对象。

不要以代码之外的规则约束代码逻辑,例如以数组的不同下标来表示不同含义。

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

Q:类之中有一个数值类型码,但它并不影响类的行为。

A:以一个新的类替换该数值类型码。

类型码本质上仍然是数值,而非对象,因而编译器无法做有效的类型检查。

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

Q:你有一个不可变的类型码。

A:以子类取代这个类型码。

在面向对象术语中,听上去最高贵的词非“多态”莫属。

将类型码用子类封装后,与类型码相关的行为和特性也就可以封装到子类中。

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

Q:你有一个类型码,它会影响类的行为,但你无法通过继承手法消除它。

A:以状态对象取代类型码。

16. Replace Subclass with Field(以字段取代子类)

Q:你的各个子类的唯一差别只在“返回常量数据”的函数身上。

A:修改这些函数,使它们返回超类中的某个(新增)字段,然后销毁子类。

没有行为只有数据的类应当被移除。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容