【问题标题】:Understanding Template method pattern了解模板方法模式
【发布时间】:2014-02-25 13:41:24
【问题描述】:

据我了解,模板方法只不过是调用子类中定义的虚拟或抽象方法的普通方法。我是对的,还是我错过了这种模式的其他重要内容?

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
}

如果我是对的,还有其他常见的方法来实现模板方法吗?

【问题讨论】:

    标签: design-patterns template-method-pattern


    【解决方案1】:

    是的。大多数模式没有什么特别之处,只是看起来很适合某些情况的聪明方法,但仍然使用正常的 OO 原则(继承、多态、抽象等)。

    模板方法的意思是有时候,你需要做一些通用的逻辑,一些子类特定的逻辑与之交错。因此,您要为每个子类保留的特定逻辑被定义为一个抽象/虚拟方法,该方法留给具体类实现,而通用业务逻辑则围绕它进行。

    如果你想确保公共逻辑不被覆盖,你也可以将模板方法标记为不被覆盖(例如Java中的final关键字),这样你就可以确保你想要的公共代码be always executed 总是被强制执行,同时允许子类覆盖你想要的位。

    把它想象成一个文档模板。标题、页脚和公共元素将固定在那里并且始终相同,然后是特定文档用于填补其间空白的具体细节。

    【讨论】:

    • 啊——终于明白为什么要使用final关键字了,谢谢! :-)
    • 酷:)。您还可以将它与类(不允许任何人覆盖它们)和变量一起使用(在这种情况下,它们的值一旦被初始化就不允许改变,它们将是不可变的)
    【解决方案2】:

    模板模式为该方法的所有子项提供了一个通用序列。所以 Template Pattern 定义了一个 final 方法来告诉执行的顺序。

    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

    【讨论】:

    • 当method1()-method3()不是虚拟或抽象时,这是否仍然是模板方法模式,所以调用initialize()不会从子类调用那些方法?
    • 啊,我明白了:所有方法都可以被覆盖的Java语法。
    • yups.. 所以你可以强制方法在java中以指定的顺序执行。
    【解决方案3】:

    HeadFirst 书中的示例。

    您必须冲泡茶和咖啡。一般来说,它们都有相同的步骤,比如开水和倒入杯子,但它们也有一些不同的步骤,例如添加调味品——茶我们可以加柠檬,咖啡我们可以加牛奶。 所以我们创建了一个通用(模板)类CaffeineBeverage,它是抽象的:

    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");
        }
    

    请注意,pourInCupboilWater 不是抽象的,因为它们对于茶和咖啡来说是完全相同的。

    现在我们创建 Tea 类,它扩展了我们的一般 CaffeineBeverage 类,我们定义了添加调味品等行为:

    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 类,它也扩展了CaffeineBeverage 类:

    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 的普通方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多