本文是在学习中的总结,欢迎转载但请注明出处:http://blog.youkuaiyun.com/pistolove/article/details/44313725
在上一篇文章中介绍了“移除中间人”。本文将介绍“引入外加函数”这种重构手法。
下面让我们来学习这种重构手法吧。
开门见山
发现:你需要为提供服务的类增加一个函数,但你无法修改这个类。
解决:在客户类中建立一个函数,并以第一参数形式传入一个服务器类实例。
//before
Date newStart = new Date(previous.getYear(),
previous.getYear(),previous.getYear() + 1);
//after
Date newStart = nextDay(previous);
private static Date nextDay(Date date){
//......
return new Date(date.getYear(),date.getMonth(),date.getDate() + 1)
}
动机
你经常会遇到这样的事情:你正在使用一个类,它很好,为你提供了很多需要的服务。而后,你又需要增加一项新服务,这个类却无法供应。于是你开始咒骂:为什么不能做这件事情呢?如果可以修改源码,你便可以自行增加一个新函数;如果不能,你就得在客户端编码,补足你要的那个函数。
如果只需要使用这个功能一次,那么额外的编码也没什么大不了的,甚至可能不需要原本提供服务的那个类。然而,如果需要多次使用这个函数,就不得不重复代码了。切记:重复代码是软件万恶之源。这些重复的代码应该被抽取出来放到同一个函数中。进行该项重构时,如果以外加函数实现一项功能,那就是一个明确信号:这个函数原本应该在提供服务的类中实现。
如果发现为一个服务类建立了大量外加函数,或者发现有许多类都需要同样的外加函数,就不应该再使用本项重构,而应该使用“引入本地扩展”。但是不要忘记:外加函数终归是权宜之计。如果有可能的话,应该将这些函数搬移到它们的理想家园。由于代码所有权的原因使你无法做这样的搬移,就把外加函数交给服务类,请它帮忙在服务类中实现这个函数。
做法
示例
Date newStart = new Date(previous.getYear(),
previous.getYear(),previous.getYear() + 1);
可以将赋值运算右侧代码提炼到一个独立函数中。这个函数就是Date类的一个外加函数:
Date newStart = nextDay(previous);
private static Date nextDay(Date date){
//......
return new Date(date.getYear(),date.getMonth(),date.getDate() + 1)
}