如果你有一个引用对象,很小且不可改变,而且不易管理,你就需要考虑将他改为一个值对象。在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. 5个数求最值—南阳acm

    问题描述  设计一个从5个整数中取最小数和最大数的程序   输入       输入只有一组测试数据,为五个不大于1万的正整数 输出      输出两个数,第一个为这五个数中的最小值,第二个为这五个数中 ...

  2. SecureCRT 实用配置

    SecureCRT,是一款支持 SSH2.SSH1.Telnet.Telnet/SSH.Relogin.Serial.TAPI.RAW 等协议的终端仿真程序,最吸引我的是,SecureCRT 支持标签 ...

  3. UVA 6199 不定根最小树形图

    首先是最小树形图的介绍. 看这个博客.最小树形图 上面介绍的很详细了,我就讲一下这道题的题意. 首先给出一些二维点坐标,这些坐标之间构成一些有向图,根据题意,假设两个点a(x1 ,y1) ,b(x2 ...

  4. 8-3-COMPETITION

    链接:8.3比赛 这次是动态规划里的LCS,LIS,LCIS专场....... A.Common Subsequence 就是:给出两个字符串,求出其中的最长公共子序列的长度~LCS 代码: //me ...

  5. linux内核--几个上下文(context)

    为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行,这种行为叫进程切换(process switch),任务切换(task switch)或上下文切换(con ...

  6. opencv学习笔记-图像对比度、亮度调节

    在数学中我们学过线性理论,在图像亮度和对比度调节中同样适用,看下面这个公式: 在图像像素中其中: 参数f(x)表示源图像像素. 参数g(x) 表示输出图像像素. 参数a(需要满足a>0)被称为增 ...

  7. javascript字符串基本方法

    1)auchor anchor() 方法用于创建 HTML 锚. var txt="Hello world!" document.write(txt.anchor("my ...

  8. 理解asp.net中DropDownList编辑数据源,绑定数据库数据。

    一.理解asp.net绑定数据库 终于学习到了连接数据库部分的内容,杨中科老师视频看起来挺轻松的,如果是高清版就更ok了. 我发现我学习新的编程语言会有一个特点,都想要赶紧学习数据库,数据就是一切,有 ...

  9. Java基础知识强化之网络编程笔记08:TCP之客户端键盘录入服务器控制台输出

    1. 客户端: package cn.itcast_08; import java.io.BufferedReader; import java.io.BufferedWriter; import j ...

  10. 必应代码搜索 Bing Code Search 安装

    微软这几天推出基于bing搜索引擎的  Bing Code Search ,可直接在浏览器上搜索和运行代码.目前中文版必应无法使用本功能,有需要的同学可以转到英文版进行搜索: 英文版必应:  http ...