处理概括关系之二 :Pull Up Method(函数上移)
来源:互联网 发布:xilinx ise软件 编辑:程序博客网 时间:2024/05/01 17:42
有些函数,在各个subclass 中产生完全相同的结果。
将该函数移至superclass。
动机(Motivation)
避免「行为重复」是很重要的。尽管「重复的两个函数」也可以各自工作得很好, 但「重复」自身会成为错误的滋生地,此外别无价值。无论何时,只要系统之内出现重复,你就会面临「修改其中一个却未能修改另一个」的风险。通常,找出重复也有一定困难。
如果某个函数在各subclass 中的函数体都相同(它们很可能是通过「拷贝-粘贴」得到的),这就是最显而易见的Pull Up Method 适用场合。当然,情况并不总是如此明显。你也可以只管放心地重构,再看看测试程序会不会发牢骚,但这就需要对你的测试有充分的信心。我发现,观察这些可疑(可能重复的〕函数之间的差异往往大有收获:它们经常会向我展示那些我忘记测试的行为。
Pull Up Method 常常紧随其他重构而被使用。也许你能找出若干个「身处不 同subclasses 内的函数」而它们又可以「通过某种形式的参数调整」而后成为相同函数。这时候,最简单的办法就是首先分别调整这些函数的参数,然后再将它们概括(generalize)到superclass中。当然,如果你自信足够,也可以一次同时完成这两个步骤。
有一种特殊情况也需要使用Pull Up Method : subclass 的函数覆写(overrides) 了superclass 的函数,但却仍然做相同的工作。
Pull Up Method 过程中最麻烦的一点就是:被提升的函数可能会引用「只出现于subclass 而不出现于superclass」的特性。如果被引用的是个函数,你可以将该函数也一同提升到superclass,或者在superclass 中建立一个抽象函数。在此过程中,你可能需要修改某个函数的签名式(signature),或建立一个委托函数(delegating method)。
如果两个函数相似但不相同,你或许可以先以Form Template Method 构造出相同的函数,然后再提升它们。
作法(Mechanics)
范例:(Example)
我以Customer「表示「顾客」,它有两个subclass :表示「普通顾客」的RegularCustomer 和表示「贵宾」PreferredCustomer。
两个subclass 都有一个createBill() 函数,并且代码完全一样:
void createBill (date Date) {
double chargeAmount = charge (lastBillDate, date);
addBill (date, charge);
}
但我不能直接把这个函数上移到superclass,因为各个subclass 的chargeFor() 函数并不相同。我必须先在superclass 中声明chargeFor() 抽象函数:
class Customer...
abstract double chargeFor(date start, date end)
然后,我就可以将createBill() 函数从其中一个subclass 拷贝到superclass。拷贝完之后应该编译,然后移除那个subclass 的createBill() 函数,然后编译并测试。 随后再移除另一个subclass 的createBill() 函数,再次编译并测试:
- 处理概括关系之二 :Pull Up Method(函数上移)
- 处理概括关系之三 :Pull Up Constructor Body(构造函数本体上移)
- 处理概括关系之一 :Pull Up Field(值域上移)
- 11.2pull up method(函数上移)
- 处理概括关系之四 :Push Down Method(函数下移)
- 处理概括关系之十 :Form Template Method(塑造模板函数)
- 处理概括关系(二)
- 《重构改善既有代码的设计》之重构列表--处理概括关系(二)
- 重构方法之处理概括关系(继承关系)
- 第3篇 上移方法 (pull method)
- 处理概括关系(一)
- 处理概括关系之六 :Extract Subclass(提炼子类)
- 处理概括关系之八 :Extract Interface(提炼接口)
- 重构之处理概括关系
- 6、处理概括关系
- 处理概括关系
- 处理概括关系之九 :Collapse Hierarchy(折叠继承关系)
- Refactoring Day 3 : Pull Up Method
- 关于MBAFF的解释
- JAVA读写Properties属性文件
- Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/Synchronization
- 新浪CDN自动化运维
- 嵌入式Linux中的读写方式研究
- 处理概括关系之二 :Pull Up Method(函数上移)
- Android 异步获取图片并缓存到本地
- 关于HTML5令人激动的10项预测
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
- 使用mp3tagiconv解决MP3乱码问题
- OpenCV学习笔记(7)—轮廓
- Installing OEM for second instance
- 什么是对分带宽/对半带宽 (bisection bandwidth)
- C++类构造函数初始化列表