据我所知,模板方法只不过是调用子类中定义的虚或抽象方法的普通方法。我说得对吗,或者我错过了这个模式的其他重要内容?
abstract class Foo {
public void IamTemplateMethod() { // which will be called in child class object
method1(); // because this...
method2(); // ...or this method was called in me
}
public virtual void method1() { ... } // to be overriden in child class
public abstract void method2() { ... } // to be defined in child class
}
如果我是对的,有没有其他常见的方法来实现模板方法?
是的。大多数模式没什么特别的,只是聪明的方法,似乎很适合某些情况,但仍然使用正常的OO原则(继承、多态、抽象等)。
模板方法说的是,有时候,你需要做一些公共逻辑,一些子类特定的逻辑与之交错。所以你想留给每个子类的特定逻辑被定义为一个抽象/虚拟方法,留给具体类来实现,而公共的业务逻辑绕着它走。
如果您想确保公共逻辑不被覆盖,您还可以将模板方法标记为不被覆盖(例如,在Java中使用last
关键字),这样您就可以确保您希望始终执行的公共代码始终被强制执行,同时允许子类覆盖您希望它覆盖的位。
把它想象成一个文档模板。标题、页脚和公共元素将是固定的并且总是相同的,然后特定文档用于填充之间的空白的具体细节。
模板模式为该方法的所有子级提供了一个公共序列跟随。因此模板模式定义了一个告诉执行顺序的最终方法。
abstract class Foo {
public void final initilialize(){
method1();
method2();
method3();
}
public void method1(){...}
public void method2(){...}
public void method3(){...}
}
现在子类可以扩展Foo类。参考可以创建为:
Foo obj1=new child();
欲了解更多信息,请查看http://www.tutorialspoint.com/design_pattern/template_pattern.htm
HeadFirst书中的示例。
你必须冲泡茶和咖啡。一般来说,它们都有相同的步骤,比如烧水和倒入杯子,但它们也有一些不同的步骤,例如添加调味品——对于茶,我们可以添加柠檬,对于咖啡,我们可以添加牛奶。所以我们创建了一个通用(模板)类CaffeineB饮料
,它是抽象的:
public abstract class CaffeineBeverage {
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
请注意,pourInGlass
和boilWater
不是抽象的,因为它们对于茶和咖啡都是完全相同的。
现在我们创建Tea
类,它扩展了我们的通用CaffeineB饮料
类,我们定义了例如添加调味品的行为:
public class Tea extends CaffeineBeverage {
@Override
public void brew() {
System.out.println("Steeping the tea");
}
@Override
public void addCondiments() {
System.out.println("Adding Lemon");
}
}
和Coffee
类,它还扩展了CaffeineB饮料
类:
public class Coffee extends CaffeineBeverage {
@Override
public void brew() {
System.out.println("Dripping Coffee through filter");
}
@Override
public void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
我们可以为模板方法设计模式创建测试类:
public class CaffeineBeverageTest {
public static void main(String[] args){
Tea tea = new Tea();
tea.prepareRecipe();
Coffee coffee = new Coffee();
coffee.prepareRecipe();
}
}
如前所述——在里面创建抽象类和方法。对不同的行为使用抽象方法,对常见行为使用带有body的普通方法。