HeadFirst 设计模式学习笔记8--模板方法模式

1.这个模式比较简单,我们举一个银行贷款申请流程程序的例子(这个并非是书中的例子):

申请贷款,银行要检查这个客户的一些事宜,譬如客户收支状况记录、从三个地方拿到他的信用记录、得到其他已有相关债务信息、得到借债人股票市值、得到借债人未来收入预期分析等等。我们可以设计如下一个模板方法:

我们的贷款类就可以如下这么设计了,实现了模板方法中的抽象方法:

2.这个模式的核心思想是“抽象”。首先作为模板方法,它必须是一个方法(废话……),它可以作为一个算法的例子,在模板方法中,每一个步骤都要由另一个方法来完成,某些方法是由这个类完成,某些则是由这个类的子类完成(需要由子类提供的方法必须在超类中声明为抽象)——模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现,实质上模板方法提供了一个算法的框架(Framework),步骤定死,而实现又子类进行。这个模式的优势在于最大限度的发挥抽象能力,保证程序需求变更或者优化升级时必须进行的变更最小。注意、包含模板方法的类本身要是抽象的。

3.我们能不能比较智能的控制算法呢,比如某些时候这个客户是一个VIP客户,我们不需要对其Income去进行检查,此时可以使用Hook(挂钩),在需要的时候把一些方法“挂上”。我们这样设计这个模板方法类:

挂钩函数除了可以让子类控制一些算法的流程以外,另一个功能是让子类有机会对模板方法中某些即将发生的步骤做出反应。

注意,由于子类必须实现抽象类中的所有抽象方法,所以应该保持抽象方法的数目越少越好,这就需要你在设计的时候对算法内的数据不要切割太细,同时粒度太大程序的弹性又受到限制,这就需要你去权衡了,程序设计中太多的地方是平衡和妥协了。

4.我们此时引出一个新的OO原则——好莱坞原则:别电话给我们,我们会打电话给你——别调用我们,我们会去调用你。

在这个原则之下,我们允许低层组件将自己挂钩到系统上,而高层组件会决定什么时候和如何使用这些低层组件,我们把决策权放到高层模块中。也就是说,高层组件对待低层组件的方式就是上边那句黑体字的原则。书中举了一个咖啡与茶的例子(有趣的是,《咖啡与茶》是丁薇早年间的一张唱片的名字,我高一的时候买到了正版卡带)来解释模板方法模式与这个原则关系,见原书(英文版)P297。这个原则和依赖倒置原则的关系是,后者交给我们如何尽量避免使用具体类,而多使用抽象,注重体现如何避免依赖。前者则是通过创建框架和组件的一种技巧,注重创建一个有弹性的设计,同时又防止其他类太过依赖它们,避免类的环状依赖。值得注意的是,工厂方法是模板方法的一种特殊版本。

5.接着,我们看看Java中有什么是使用了这个模式的:数组排序方法sort( )

sort()的设计者希望这个方法能适用于所有的数组,所以将其设置为静态方法。而同时你必须实现compartTo方法后才能使用sort方法,为了达到这一点,设计者利用了Comparable接口,提供这个接口所声明的方法,也就是compartTo。

我们现在利用这个接口去设计一个鸭子的类,试图根据体重去对鸭子进行比较。

这样,我们就能直接使用数组中的sort方法了:

这和模板方法又有什么关系呢?

完成Comparable接口的compareTo方法使得元素自行提供比较大小的算法部分。这就有点像前边我们的贷款程序中自己定义如何检查客户收入的函数一样。

我们再举两个例子:Swing:

Applet:具体的applet大量使用挂钩函数提供行为。

6.最后,我们比较一下模板方法模式和策略模式的异同。

前者定义一个算法的大纲,由子类(注意这里是继承)定义其中的某些步骤的内容,这样算法的细节可有不同,但是算法的结构和流程保持不变,它对算法有更多的控制权。而后者定义了一个算法的家族,并让这些算法互换,正因为每一个算法都被封装了起来,所以客户可以轻易地使用不同的算法(不是通过继承而是接口的组合),它则更有弹性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值