一、意图
定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
二、适用性
1.一次性实现一个算法的不变部分,并且将可变的行为留给子类来完成。
2.各子类的公共行为应该被提取出来并集中到一个公共父类中以避免代码的重复。首先识别现有代码的不同之处,并且把不同的部分分离为新的操作,最后,用一个这些新的操作的模板方法来替换这些不同的代码。
3.控制子类的扩展。
三、组成
—父类角色:提供模板
—子类角色:为模板提供实现
四、结构
五、简单实现
父类,定义算法框架,规定了步骤。
package com.pattern.teplateMethod;
public abstract class AbstractClass
{
public void template()
{
this.method1();
this.method2();
this.method3();
}
public abstract void method1();
public abstract void method2();
public abstract void method3();
}
此处显然只能使用抽象类而不能使用接口。
子类,实现算法的步骤,而不会改变算法的框架。
package com.pattern.teplateMethod;
public class ConcreteClass extends AbstractClass
{
@Override
public void method1()
{
System.out.println("do something in method1");
}
@Override
public void method2()
{
System.out.println("do something in method2");
}
@Override
public void method3()
{
System.out.println("do something in method3");
}
}
客户端测试:
package com.pattern.teplateMethod;
public class Client
{
public static void main(String[] args)
{
AbstractClass ac=new ConcreteClass();
ac.template();
}
}
六、对模板方法进行挂钩
钩子是一种被声明在抽象类中的方法,但是只有空的或默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩,要不要挂钩,由子类自行决定(实际上就是子类选择是否覆盖父类中的空实现的方法来进行扩展)。
如果算法的某个部分是可选的,就可以使用钩子,子类可以选择实现这个钩子但并不强制这么做。在钩子对于子类的实现并不重要的时候,子类可以对此钩子置之不理
如下,在父类中简单定义两个钩子:
public abstract class AbstractClass
{
public void template()
{
this.before();//钩子
this.method1();
this.method2();
this.method3();
this.after();//钩子
}
public abstract void method1();
public abstract void method2();
public abstract void method3();
//钩子一般是父类中空实现的方法,供子类选择是否对其覆盖(以便进行扩展)
public void before()
{}
public void after()
{}
}
七、好莱坞原则
好莱坞原则是:“别调用(打电话给)我们,我们会调用(打电话给)你”。
在好莱坞原则之下,我们允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些低层组件。换句话说,高层组件对待低层组件的方式是:”别调用我们,我们会调用你“。
好莱坞原则强调高层对低层的主动作用,即低层应该只管好自己的工作(具体实现),而高层自有它自己的工作,在不需要到某个低层的时候,高层并不会调用到这个具体低层,低层永远不需要向高层作出表示,说它需要被调用。
八、其他
1.为防止子类改变模板方法中的算法,可以将模板方法声明为final。
2.好莱坞原则与依赖倒置原则的关系:
依赖倒置原则教我们尽量避免使用具体类,而多使用抽象。而好莱坞原则是用在创建框架或组件上的一种技巧,好让低层组件能够被挂钩进计算中,而且又不会让高层组件依赖低层组件。两者的目标都是在于解耦,但是依赖倒置原则更加注重如何在设计中避免依赖。
3.低层组件可以调用高层组件中的方法(实际上子类会常常调用其从父类中继承所来的方法),但是我们要做的是要避免让高层和底层组件之间有明显的环状依赖。
4.策略模式和模板方法模式都封装算法,但是策略模式使用的是组合,模板方法模式使用的是继承。
5.工厂方法是模板方法的一种特殊版本。
转载请注明出处:http://blog.youkuaiyun.com/jialinqiang/article/details/8866977