『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method
当你无法获得一个类的源代码或者没有权限去修改这个类的时候,你对于这种为你服务的类,你可能会出现需要别的需求的时候,比如一个Date类,你需要能够让他本身直接返回出他的后一天的对象,但他没有,这个时候你就需要暂时使用Introduce Foreign Method来做过渡,并且在适当时候通知作者把这个Foreign Method搬移到他所属于的自己的类中去。
这种情况其实也很多,特别是当你在团队当中,当有别人写了一个类的时候,你会去利用这个类去做你想要做的事情,但如果你发现这个类并没有提供你所要的功能,如果你可以去修改源代码,那当然可以。你可以直接在类的源代码中增加一行你所想要的功能。但如果你不能获取源代码,你就只能在客户端编码,补充你所想要的那个函数。
当然,如果你所处的客户类只使用这项功能一次,那没什么大不了,你可以完全额外添加多出来的处理逻辑。甚至你可能都不需要原来提供服务的那个对象本身,但是,如果你需要多次去使用这个函数,你就不得不去重复这些代码,还记得吗
重复代码是软件的万恶之源。
这些重复代码应该被抽出来运用Extract Method放进同一个函数中去,当然如果你迫不得已执行本次重构,这也给了你一个明确的信号:这个函数原本应该在提供服务的类中实现。
如果你发现自己已经为一个服务类增加的大量函数,或者发现有许多类都需要同样的外加函数,你就不应该再使用本次重构,而应该使用Introduce Local Extension。但是请不要忘记,Foreign Method始终是权宜之计,如果有可能,你仍然应该将这些函数通过Move Method搬移到他们的理想家园。如果你无法进行这样的搬移,你也可以把这个外加函数交给服务类的拥有者,请他帮你在服务类中实现这个函数。
做法:
- 在客户类中建立一个函数,用来提供你需要的功能。这个函数不应该调用客户类的任何特性,如果他需要一个值,把值当作传输传给他,而不是让他在函数内部本身去调用你客户类的特性。在这里有一个技巧,为了避免之前说的那种可能会让你提炼的函数引用客户类的特性,我们可以在新创建的函数给他static特性,大家都知道C++的static会迫使你不能去接触所属类的特性。
- 以服务类实例作为这个函数的第一个参数。
- 将该函数注释为“foreign method应该在服务类中实现”来提醒你将来有机会将外加函数搬移道服务类中的时候可以很快速的找到这些函数。
例子:
Date newStart = new Date(perviousEnd.getYear(), perviousEnd.getMonth(), perviousEnd.getDate()
+ );
在例子中我们可以看到,我在客户端代码里需要一个跨越一个收费周期的函数,但实际Date并不提供这个函数,所以我只能自己写一个冗长的new。当然,如果出现一处这种地方我们不需要太在意,但是如果出现多出,我们就需要使用Extract Method进行重构,这个函数就是Date类的外加函数。我们可以这么声明
Date newStart = nextDay(perviousEnd); static Date nextDay(Date arg)
{
// foreign method, should be on Date
return new Date(arg.getYear(), arg.getMonth(), arg.getDate()
+ );
}
可以看到,我们让这个函数变成static这样可以保证我们不使用客户端类的任何特性,同时我们把这个函数的第一个参数作为服务类对象传进,这样我们以后在进行Move Method的时候可以得到无参化的简洁接口。
『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method的更多相关文章
- 『重构--改善既有代码的设计』读书笔记----Introduce Local Extension
同Introduce Foreign Method一样,很多时候你不能修改编辑原始类,你需要为这些服务类增加一些额外的函数,但你没有这个权限或者入口.如果你只需要一个或者两个外加函数那么你可以放心的使 ...
- 『重构--改善既有代码的设计』读书笔记----Introduce Explaning Variable
有时候你会遇到一系列复杂的表达式连续运算的时候,这个时候你可能根本招架不住如此长或者是如此复杂的长函数.这个时候你可以通过引用临时变量来储存他们的结果,将这些长函数的结果分成一个个临时变量来让函数清晰 ...
- 『重构--改善既有代码的设计』读书笔记----Extract Method
在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...
- 『重构--改善既有代码的设计』读书笔记----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
明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...
随机推荐
- loadrunner打不开ie&ie默认浏览器设置方法
loadrunner使用过程中频繁的出现问题,出现次数最多的就是lr打不开ie,或者ie一闪就关闭了,问题出在我默认浏览器的设置上,因为我原先并没有成功设置ie为默认浏览器.这是一个无意识的错误,我以 ...
- Android中的资源文件
最近复习Android资源文件的内容,留下点记录以备后用. Android中的资源主要是指存放在应用程序或者Framework相应包下/res中的内容.它们可以被本地化,如果必要的话会被编译成二进制文 ...
- TOYS - POJ 2318(计算几何,叉积判断)
题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数. 分析:做的第一道计算几何题目....使用叉积判断方 ...
- FIREDAC TFDCONNECTION连接MYSQL数据库
FIREDAC TFDCONNECTION连接MYSQL数据库 procedure TfrmDB.ConnectDB;begin FDMoniFlatFileClientLink1.FileName ...
- 找出Active Directory架构操作主机方法!
- HTTP 返回时间 概念 TTFB..
课外学习部分: 什么是TTFB呢? 1.TTFB (Time To First Byte),是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了 TCP连接时间,发送HTTP请求时间和获 ...
- win8 64位 mysql安装 Configuration file my.ini error code -1
问题如题,解决方法: 1.由于目录中纯在中文,所以导致代码错误.故而把目录设置成全英文的. 2.下载64位mysql安装,安装32位mysql也会出现此问题.
- TopCoder SRMS 1 字符串处理问题 Java题解
Problem Statement Let's say you have a binary string such as the following: 011100011 One way to e ...
- 韩玉琪 《Linux内核分析》MOOC课程
http://www.cnblogs.com/hyq20135317/p/5422516.html http://mooc.study.163.com/course/USTC-1000029000
- 利用systemtap学习Linux路由代码
http://bbs.chinaunix.net/thread-4090162-1-1.html 一.为什么要这样做读kernel route子系统代码,当我弄懂了数据结构之间的关系以及控制流程后,心 ...