如果你有一个引用对象,很小且不可改变,而且不易管理,你就需要考虑将他改为一个值对象。在Change Value to Reference我们说过,要在引用对象和值对象之间做选择,有时候并不容易,有了重构,做出选择之后,你还有一条回头路。

如果你发现引用对象开始变得难以使用,你就考虑是否应该把它改为值对象。引用对象必须被某种方式控制,你总是必须向其控制者请求适当的引用对象。如果你让你造成在你系统内存之间变得错综复杂。或者在分布系统和并发系统中,不可变值特别有用(你需要考虑可变对象引用对象他们的同步关系)。

值对象有一个非常重要的特性----它应该是不可变的。无论何时,只要你调用同一个对象的同一个查询函数,它返回的结果应该是一样的。如果你可以保证这一点,你可以放心的让多个对象表示同一个事物。如果值对象是可变的,你就必须确保某一个对象的修改会自动更新到其他代表相同事物的对象中去。那此时你应该使用引用对象了。

什么是不可变?不可变意味着如果你以Money来表示金钱,那么Money通常是一个不可变的值。这并不是意味着你的金钱不能改变。而是意味着如果你改变薪资,你必须用另一个对象来替换现在的Money对象,而不是在现在的Money对象上做修改。注意这里面的说法,这种改变就类似与我们原子级别的内置变量,举个例子

int age = ;

age = ; // right

age = int(13).setIntValue(); // false

对于内置类型int来说就是一个最简单的值类型,我们的年龄age在从13改变到14的时候,正是替换了现在的对象,产生了一个int(14)而不是直接在13对象上做修改。对于Money来说

Money mon = Money();

mon = Money(); // right

mon = mon.setValue(); // false

我们的mon也是做了对象的替换,而不会去采用setValue的形式去做修改。始终记住:值对象本身是不可修改的

  • 做法:
  • 检查重构目标,是否为不可变对象,或是否可以修改为不可变对象。如果该对象目前还不是不可变的,就使用Remove Setting Method直到它成为不可变为止。如果你实在无法将该对象修改为不可变,就放弃本次重构。
  • 建立“==”函数和hashCode()(Java)。
  • 编译,测试。
  • 考虑是否可以删除工厂函数,并将构造函数声明为public。

例子:

class Currency
{
private:
Currency(const QString &code) :
m_code(code)
{
}
public:
 QString code() const
{
return m_code;
}
private:
QString m_code;
};

这个货币类目前是一个引用对象,我们现在想得到他,必须通过这种方法

Currency *usd = Currency::get("USD");

Currency内部维护一个Hash表用来保存预先创建好的Currency实例,我们也不能直接通过构造函数来构造他们,因为此时的构造函数是私有的。要把一个引用对象变成值对象,关键动作是观察它是否可变,如果他可变,那就别用此次重构,因为后期的别名同步问题还很烦人。在这里Currency是不可变的,我们为它重载==

bool operator==(const Currency &value)
{
if (this == &value)
{
return true;
}
else
{
return this->m_code == value.code();
}
}

完成这个之后我们进行编译,测试。现在我们想创建多少个Currency都没问题,我们还可以把他的构造函数声明为public,我们可以直接用构造函数来获取Currency实例,从而去掉工厂函数和控制实例创建的行为。

『重构--改善既有代码的设计』读书笔记----Change Reference to Value的更多相关文章

  1. 『重构--改善既有代码的设计』读书笔记----Change Value to Reference

    有时候你会认为某个对象应该是去全局唯一的,这就是引用(Reference)的概念.它代表当你在某个地点对他进行修改之后,那么所有共享他的对象都应该在再次访问他的时候得到相应的修改.而不会像值对象(Va ...

  2. 『重构--改善既有代码的设计』读书笔记----Extract Method

    在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...

  3. 『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object

    有时候,当你遇到一个大型函数,里面的临时变量和参数多的让你觉得根本无法进行Extract Method.重构中也大力的推荐短小函数的好处,它所带来的解释性,复用性让你收益无穷.但如果你遇到上种情况,你 ...

  4. 『重构--改善既有代码的设计』读书笔记---Duplicate Observed Data

    当MVC出现的时候,极大的推动了Model与View分离的潮流.然而对于一些已存在的老系统或者没有维护好的系统,你都会看到当前存在大把的巨大类----将Model,View,Controller都写在 ...

  5. 『重构--改善既有代码的设计』读书笔记----Replace Array with Object

    如果你有一个数组,其中的元素各自代表不同东西,比如你有一个 QList<QString> strList; 其中strList[0]代表选手姓名,strList[1]代表选手家庭住址,很显 ...

  6. 『重构--改善既有代码的设计』读书笔记----Self Encapsulate Field

    如果你直接访问一个字段,你就会和这个字段直接的耦合关系变得笨拙.也就是说当这个字段权限更改,或者名称更改之后你的客户端代码都需要做相应的改变,此时你可以为这个字段建立设值和取值函数并且只以这些函数来访 ...

  7. 『重构--改善既有代码的设计』读书笔记----Move Method

    明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...

  8. 『重构--改善既有代码的设计』读书笔记----Replace Data Value with Object

    当你在一个类中使用字段的时候,发现这个字段必须要和其他数据或者行为一起使用才有意义.你就应该考虑把这个数据项改成对象.在开发初期,我们对于新类中的字段往往会采取简单的基本类型形式来保存,但随着我们开发 ...

  9. 『重构--改善既有代码的设计』读书笔记----Substitute Algorithm

    重构可以把复杂的东西分解成一个个简单的小块.但有时候,你必须壮士断腕删掉整个算法,用简单的算法来取代,如果你发现做一件事情可以有更清晰的方式,那你完全有理由用更清晰的方式来解决问题.如果你开始使用程序 ...

随机推荐

  1. javascript函数定义表达式和函数声明的区别

    在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ ...

  2. hdoj 2063 过山车【匈牙利算法+邻接矩阵or邻接表】

    过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  3. JavaFX 3D部分介绍(3) Lights

    声明:   本博客文章原创类别的均为个人原创,版权所有.转载请注明出处: http://blog.csdn.net/ml3947,另外本人的个人博客:http://www.wjfxgame.com. ...

  4. Gof-23种设计模式名称列表

    工欲善其事,必先利其器. 在真正使用设计模式之前,必须知道各个设计模式对应的场景.设计模式是针对某种固定的场景下产生的固定解决方案.只有明确的场景,才会有明确的设计方式和方法. 设计模式全集: Abs ...

  5. kafka consumer 分区reblance算法

    转载请注明原创地址 http://www.cnblogs.com/dongxiao-yang/p/6238029.html 最近需要详细研究下kafka reblance过程中分区计算的算法细节,网上 ...

  6. DS18B20测温

    项目需要实现分布式大规模测温,需要52个测温点,采样DS18B20进行设计. 30cm一个点,一共8个点串联.采用国标单芯单股纯铜硬线BV0.5做导线,测试一会儿正常,一会儿不正常.后面换线了,测试正 ...

  7. [D3] 13. Cleaner D3 code with selection.call()

    selection.call() method in D3 can aid in code organization and flexibility by eliminating the need t ...

  8. 史上比较用心的纯代码实现 AutoLayout

    入职有两三个月了吧,都是使用 Objective-C 纯代码(虽然有时候偷偷参杂一些 Swift 开源库)来编写公司APP,写布局的时候几乎都是要么在初始化的时候用 initWithFrame,要么就 ...

  9. swift Array 数组

    // //  main.Swift //  swift数组 // //  Created by zhangbiao on 14-6-15. //  Copyright (c) 2014年 理想. Al ...

  10. Hack工具

    黑客工具一般是由黑客或者恶意程序安装到您计算机中,用来盗窃信息.引起系统故障和完全控制电脑的恶意软件程序.同时也指黑客进行黑客任务时使用的工具.著名的有nmap,流光等等. 目录 1 种类 2 恶意程 ...