『重构--改善既有代码的设计』读书笔记----Hide Delegate
所谓委托关系,就是一个类对于另一个类来说纯粹作为接口转发,即客户通过一个委托类去调用另一个对象。直白的委托关系就是委托类直接返回出目标类给客户调用,这个关系很麻烦,因为委托关系的变动就会影响客户端的代码。隐秘的委托关系很健康,当你完全隐藏之后,你委托关系的变化只会发生在委托类的内部,从而不会去影响客户。
封装是面向对象最关键的特征之一。他意味着系统的每个对象都应该尽可能少的了解系统的其他部分,这样带来的好处就是一旦发生了变化之后,需要了解到这一变化的对象就比较少,这也就意味着你需要改动的代码可以很少,让变化可以更加容易的进行。
在C++中你可以光明正大的把字段声明为public,但你应该还是尽量去隐藏这种字段,公开暴露这种字段带来的麻烦可以很多,应该尽量使用protected或者private。随着你开发经验的日渐丰富,你会发现有很多别的东西也可以进行封装。
如果客户需要通过一个服务对象(委托对象)从而得到另一个对象去调用另一个对象的函数,那么客户就必须要知道这一层委托关系,万一委托关系发生变化,客户也得相应变化。你可以在服务对象上放置一个简单的委托函数,将委托关系隐藏起来,从而去除这种依赖。这样一来,如果以后委托关系发生变化,变化也只被限制在服务对象中,不会涉及到客户。对于某些或全部客户,你可能会发现,有必要先使用Extract Class,一旦你对所有客户都隐藏了关系,就不再需要在服务对象中公开被委托对象了。
做法:
- 对于每一个委托关系中的函数,在服务对象中建立一个简单的委托函数。
- 调整客户,另他只调用服务对象提供的函数。
- 每次调整后进行编译,测试。
- 如果将来不再有任何客户需要显示去获得受托类,那么你就可以彻底移除服务对象中的相关访问函数。
- 编译,测试。
例子:
class Person
{
Department *department() const
{
return m_department;
} void setDepartment(Department *value)
{
m_department = value;
} private:
Department *m_department;
}; class Department
{
public:
Department(Person *person) :
m_manager(person)
{
}
Person *manager() const
{
return m_manager;
}
private:
QString m_chargeCode;
Person *m_manager;
};
我们可以看到有Person和Department这两个类,我们来看下客户端代码,如果我有一个Person,我想要去获取他的manager,我们就必须先调用得到他的department然后再去调用mana
manager = john->department()->manager();
可以看到,这种调用方式无疑暴露了客户端代码对于Department类的工作原理,我们可以得到原来是Department用来跟踪经理信息的这条逻辑。这样无疑增加了客户代码和Department之间的耦合,要消除这种耦合我们就必须Hide Delegate在Person中建立委托函数
class Person
{
public:
Person *manager()
{
m_department->manager();
}
};
然后我们修改客户端代码,让他转而调用新函数。
manager = john->manager();
可以看到,经过这一次修改之后,客户端代码对Department一无所知,这样无论我Person类内部与Department之间进行何种改变,我客户端代码都是稳定的。甚至如果我们完成了对Department的所有函数的委托之后,并相应修改了Person的所有客户,我就可以移除Person中对Department的访问函数了。
ger
『重构--改善既有代码的设计』读书笔记----Hide Delegate的更多相关文章
- 『重构--改善既有代码的设计』读书笔记----Extract Method
在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...
- 『重构--改善既有代码的设计』读书笔记----Remove Middle Man
如果你发现某个类做了过多的简单委托动作,你就可以考虑是否可以让客户直接去调用受托类.在Hide Delegate中,我们介绍了封装受托对象的好处,但好处归好处也存在代价,就是当你每次需要在受托对象中增 ...
- 『重构--改善既有代码的设计』读书笔记----Change Value to Reference
有时候你会认为某个对象应该是去全局唯一的,这就是引用(Reference)的概念.它代表当你在某个地点对他进行修改之后,那么所有共享他的对象都应该在再次访问他的时候得到相应的修改.而不会像值对象(Va ...
- 『重构--改善既有代码的设计』读书笔记----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
当你在一个类中使用字段的时候,发现这个字段必须要和其他数据或者行为一起使用才有意义.你就应该考虑把这个数据项改成对象.在开发初期,我们对于新类中的字段往往会采取简单的基本类型形式来保存,但随着我们开发 ...
随机推荐
- git bash【初级入门篇】
最近公司打算使用git代替之前的svn版本控制工具,趁此机会打算好好学学git,这个号称当今世界最牛的分布式版本控制工具. 一.[git和svn的主要区别] 1.去中心化 svn以及微软的TFS均采用 ...
- 佛山Uber优步司机奖励政策(1月25日~1月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误
/** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeExcepti ...
- java_method_readFile读取文件文本txt
/** * @Title: TxtAndCsvUtils.java * @Package cn.com.qmhd.tools * @Description: TODO(读取txt和CSV文档) * @ ...
- c#调用钩子
1 概述 在c++中有钩子程序,但是在C#还没有对其进行封装,所以需要自己根据实际情况调用钩子.钩子在我的理解下是,通过初始化钩子与系统中消息映射建立某种关系,当点击鼠标或者键盘,就会通过钩子中的回调 ...
- iOS开发雕虫小技之傻瓜式定位神器-超简单方式解决iOS后台定时定位
1.概述 由于公司一款产品的需求,最近一直在研究iOS设备的后台定位.主要的难点就是,当系统进入后台之后,程序会被挂起,届时定时器.以及代码都不会Run~ 所以一旦用户将我的App先换到了后台,我的定 ...
- CSS3弹性盒模型之Flexbox是布局模块box-sizing & box-orient & box-direction & box-ordinal-group
css3 box-sizing属性 box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,bord ...
- 习WebSocket一(WebSocket初识)[转]
http://www.cnblogs.com/wgp13x/p/3812579.html Java EE 7 去年刚刚发布了JSR356规范,使得WebSocket的Java API得到了统一,Tom ...
- [RxJS] Aggregating Streams With Reduce And Scan using RxJS
What is the RxJS equivalent of Array reduce? What if I want to emit my reduced or aggregated value a ...
- 利用systemtap学习Linux路由代码
http://bbs.chinaunix.net/thread-4090162-1-1.html 一.为什么要这样做读kernel route子系统代码,当我弄懂了数据结构之间的关系以及控制流程后,心 ...