【模式定义】
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
【解决问题】
泡咖啡,泡茶。其实两者都差不多,具体流程类似,只有部分内容不同。
【最初实现】
定义两个不同的类:Coffee、Tea。他们的代码相似,有很多重复的代码,不是一个好的实现。应该把相同的部分抽取出来,放在一个基类。
【逐步改善】
1.部分抽取
----这样,在各个子类里,还是要覆盖这些它的流程,重新实现不同的部分。但是,流程也是类似的,没有必要再子类里实现流程的逻辑控制。这部分继续抽象。
2.再次抽取
----把控制流程也抽取出来,并定义为final的,不允许子类改变流程(符合下面说到的设计原则)。需要由子类实现的,定义为abstract,而共有的方法,在父类里实现即可。
再来两个Tea、Coffee子类继承这个基类,并实现抽象的方法。
3.添加钩子
我们可以有“默认不做事的方法”,我们成为“钩子”(hook)。子类可以视情况是否覆盖它们。如上面的函数。通常是空的缺省的实现(只是返回true,什么也不做)。如果我们需要调料,那么,在子类里,可以这么实现这个方法,进而提供自己的功能。
【设计原则】
好莱坞原则——别调用(打电话给)我们,我们会调用(打电话给)你。
----换句话说,允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎么使用这些低层组件。
模板模式符合这样的原则。(工厂模式、观察者模式也符合。)基类控制整个冲泡的算法,只有在需要到具体的实现时,才会调用到子类。子类只是简单地提供一些实现细节。而外部的客户,也只依赖与基类抽象,而不依赖具体的Tea或Coffee。减少整个系统的依赖。
【具体实现】
1.排序
----的确很荒野…基本思想是这样的,我们提供的是低层的具体实现,但整体的流程是有高层决定的。
2.Swing JFrame的paint()函数
----当需要时,重载,实现它。钩子。
3.Applet
----提供了好多的钩子,init(),start(),stop(),等等。也是需要时,就是实现这些钩子。具体的流程,怎么处理,在基类里实现。
【与策略模式比较】
按我的理解。策略模式,是算法的组合。整个的解决流程,是由这些算法族的组合而解决的。而模板模式,它分来高低层,在高层是算法的逻辑控制,以及一些公有方法的实现。在子类里,只需要实现具体的细节。策略,是对象的组合。模板,使用的是继承。