『重构--改善既有代码的设计』读书笔记----Change Reference to Value
如果你有一个引用对象,很小且不可改变,而且不易管理,你就需要考虑将他改为一个值对象。在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的更多相关文章
- 『重构--改善既有代码的设计』读书笔记----Change Value to Reference
有时候你会认为某个对象应该是去全局唯一的,这就是引用(Reference)的概念.它代表当你在某个地点对他进行修改之后,那么所有共享他的对象都应该在再次访问他的时候得到相应的修改.而不会像值对象(Va ...
- 『重构--改善既有代码的设计』读书笔记----Extract Method
在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...
- 『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object
有时候,当你遇到一个大型函数,里面的临时变量和参数多的让你觉得根本无法进行Extract Method.重构中也大力的推荐短小函数的好处,它所带来的解释性,复用性让你收益无穷.但如果你遇到上种情况,你 ...
- 『重构--改善既有代码的设计』读书笔记---Duplicate Observed Data
当MVC出现的时候,极大的推动了Model与View分离的潮流.然而对于一些已存在的老系统或者没有维护好的系统,你都会看到当前存在大把的巨大类----将Model,View,Controller都写在 ...
- 『重构--改善既有代码的设计』读书笔记----Replace Array with Object
如果你有一个数组,其中的元素各自代表不同东西,比如你有一个 QList<QString> strList; 其中strList[0]代表选手姓名,strList[1]代表选手家庭住址,很显 ...
- 『重构--改善既有代码的设计』读书笔记----Self Encapsulate Field
如果你直接访问一个字段,你就会和这个字段直接的耦合关系变得笨拙.也就是说当这个字段权限更改,或者名称更改之后你的客户端代码都需要做相应的改变,此时你可以为这个字段建立设值和取值函数并且只以这些函数来访 ...
- 『重构--改善既有代码的设计』读书笔记----Move Method
明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...
- 『重构--改善既有代码的设计』读书笔记----Replace Data Value with Object
当你在一个类中使用字段的时候,发现这个字段必须要和其他数据或者行为一起使用才有意义.你就应该考虑把这个数据项改成对象.在开发初期,我们对于新类中的字段往往会采取简单的基本类型形式来保存,但随着我们开发 ...
- 『重构--改善既有代码的设计』读书笔记----Substitute Algorithm
重构可以把复杂的东西分解成一个个简单的小块.但有时候,你必须壮士断腕删掉整个算法,用简单的算法来取代,如果你发现做一件事情可以有更清晰的方式,那你完全有理由用更清晰的方式来解决问题.如果你开始使用程序 ...
随机推荐
- 用LINQPad加上Tx驱动来分析log
Tx (LINQ to Logs and Traces)是微软发布的开源工具.可以用这个工具来使用LINQ分析日志,包括 Event Tracing for Windows (ETW) Event L ...
- 半斤八两(创业兴家版 打工仔心声'98 Remix)
创业兴家打工仔 刻苦工作热诚日夜维系天天专心向上依足正轨 结力好比兄弟努力一生打工仔 相亲相爱朋情日夜传递彼此一家那用分高与低 要互相多鼓励 半斤八两 莫记往昔的创伤半斤八两 面对春光应插秧半斤八两 ...
- 怎样克服 JavaScript 框架疲劳?
[编者按]Tero Parviainen 著有 Build Your Own AngularJS,曾两次组织 Clojure CUP 竞赛,在 Twitter 上有近两千名关注者. 在本文中.Tero ...
- WPF combobox 圆角制作
修改ComboBox的Template, 在VS 2010或者Blend中你可以导出ComboBox的默认模板: VS2010中: 然后修改里面的模板,比如: <Window x:Class=& ...
- kafka介绍和集群环境搭建
kafka概念: kafka是一个高吞吐量的流式分布式消息系统,用来处理活动流数据.比方网页的訪问量pm,日志等,既可以实时处理大数据信息 也能离线处理. 特点: ...
- PureMVC(JS版)源码解析(五):SimpleCommand类
之前我们对PureMVC中涉及到观察者模式的三个基本类(Notification/Observer/Notifier)进行了分析,接下来将对PureMVC源码中的其他类进行分析,首先我们讲 ...
- android开发之SwipeListView的使用
实现一种类似于qq中滑动列表的功能: 向左或者向右滑动,然后执行相关操作. 这里用到的是GitHub上的开源控件SwipeListView,下载地址https://github.com/47deg/a ...
- WSDL阅读方法
我们以天气预报WebService服务为例,来看看怎么阅读一个wsdl文档. 打开一个wsdl文档后,先看底部. binding在这里: portType在这里: 好了,看了上面的,我们来说说wsdl ...
- Java基础知识强化之集合框架笔记52:Map集合之Map集合的遍历 键找值
1. Map集合的遍历 Map -- 夫妻对 思路: A:把所有的丈夫给集中起来. B:遍历丈夫的集合,获取得到每一个丈夫. C:让丈夫去找自己的妻子. 转换: A:获取所有的键 B:遍 ...
- Android(java)学习笔记185:xml文件生成
1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...