// 钩子方法
public void template()
{
open();
display();
if(isPrint())
{
print();
}
}
public boolean isPrint()
{
return true;
}
// 抽象类
public abstract class AbstractClass
{
public void templateMethod() //模板方法
{
primitiveOperation1();
primitiveOperation2();
primitiveOperation3();
}
public void primitiveOperation1() //基本方法—具体方法
{
//实现代码
}
public abstract void primitiveOperation2(); //基本方法—抽象方法
public void primitiveOperation3() //基本方法—钩子方法
{
}
}
// 具体子类
public class ConcreteClass extends AbstractClass
{
public void primitiveOperation2()
{
//实现代码
}
public void primitiveOperation3()
{
//实现代码
}
}
这里重点介绍一下钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。 通常抽象类给出的实现是一个空实现,作为方法的默认实现。 这种空的钩子方法叫做“Do Nothing Hook”。 钩子方法的名字应当以do开始,这是熟悉设计模式的Java开发人员的标准做法。
设计钩子方法的主要目的是干预执行流程,使得控制行为流程更加灵活,更符合实际业务的需求。钩子方法的返回值一般为适合条件分支语句的返回值(如boolean、int等)。小伙伴们可以根据自己的业务场景决定是否需要使用钩子方法。
模板方法模式的优点
模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。
模板方法模式是一种代码复用的基本技术。
模板方法模式导致一种反向的控制结构,通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,符合“开闭原则”。
模板方法模式的缺点
每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高
public void runBare() throws Throwable {
setUp();
try {
runTest();
}
finally {
tearDown();
}
}
1)关于继承的讨论
模板方法模式鼓励我们恰当使用继承,此模式可以用来改写一些拥有相同功能的相关类,将可复用的一般性的行为代码移到父类里面,而将特殊化的行为代码移到子类里面。这也进一步说明,虽然继承复用存在一些问题,但是在某些情况下还是可以给开发人员带来方便,模板方法模式就是体现继承优势的模式之一。
2)好莱坞原则
在模板方法模式中,子类不显式调用父类的方法,而是通过覆盖父类的方法来实现某些具体的业务逻辑,父类控制对子类的调用,这种机制被称为好莱坞原则(Hollywood Principle),好莱坞原则的定义为:“不要给我们打电话,我们会给你打电话(Don‘t call us, we’ll call you)”。
在模板方法模式中,好莱坞原则体现在:子类不需要调用父类,而通过父类来调用子类,将某些步骤的实现写在子类中,由父类来控制整个过程。
3)钩子方法的使用
钩子方法的引入使得子类可以控制父类的行为。
最简单的钩子方法就是空方法,也可以在钩子方法中定义一个默认的实现,如果子类不覆盖钩子方法,则执行父类的默认实现代码。
比较复杂一点的钩子方法可以对其他方法进行约束,这种钩子方法通常返回一个boolean类型,即返回true或false,用来判断是否执行某一个基本方法。