天天看点

设计模式---模板方法(Template Method)模式

1. 什么是模板方法模式?

在父类中定义处理流程的框架,在子类中实现具体的处理。

从字面上理解,模板方法模式是带有模板功能的模式,而组成模板的方法被定义在父类中。这些方法基本上都是抽象方法,模板只是规定了处理的流程或者步骤。

子类实现了这些抽象方法的具体处理,在不同的子类中实现不同的具体处理,当父类的模板方法被调用时也就有不同的具体实现。但是,无论子类的具体实现是怎样的,处理流程都会按照父类中所定义的进行。

2. 模板方法模式中的角色

模板方法模式相对比较简单,只有两个角色

设计模式---模板方法(Template Method)模式
  • AbstractClass(抽象类)

    AbstractClass主要负责实现模板方法,以及声明在模板方法中是用到的抽象方法,这些抽象方法有ConcreteClass实现。如果模板方法中的某些方法具有共同的行为,那么AbstractClass也负责实现这行行为。

  • ConcreteClass(具体类)

    ConcreteClass负责具体实现AbstractClass中定义的抽象方法,这些方法将会在AbstractClass的模板方法中被调用。

3. 示例代码

为了方便理解,写一个简单的程序来直观的演示一下模板方法模式。

程序是模拟把动物放进冰箱的操作,除了著名的把大象放进冰箱,我们再增加一个把猪放进冰箱。

抽象类

public abstract class AnimalRefrigerator {

   /**
    * 所有子类共同的行为,所有在父类就实现
    */
   public void open() {
       System.out.println("把冰箱门打开。");
   }

   /**
    * 不同的子类有不同的实现,所以定义成抽象方法,具体实现交给子类。
    */
   public abstract void put();

   /**
    * 所有子类共同的行为,所有在父类就实现
    */
   public void close() {
       System.out.println("把冰箱门关上。");
   }

   /**
    * 模板方法,规定了把动物放进冰箱的流程
    * 1.open() 把冰箱门打开
    * 2.put() 把动物放进冰箱
    * 3.close() 把冰箱门关上
    */
   public final void work() {
       open();
       put();
       close();
   }
}
           

具体类

public class PigRefrigerator extends AnimalRefrigerator {

   @Override
   public void put() {
       System.out.println("把猪放进冰箱里。");
   }
}
           
public class ElephantRefrigerator extends AnimalRefrigerator {

   @Override
   public void put() {
       System.out.println("把大象放进冰箱里。");
   }
}
           

Test类

public class Test {

   public static void main(String[] args) {

       AnimalRefrigerator pig = new PigRefrigerator();
       System.out.println("把猪放进冰箱分为几步:");
       pig.work();

       AnimalRefrigerator elephant = new ElephantRefrigerator();
       System.out.println("把大象放进冰箱分为几步:");
       elephant.work();
   }
}
           

运行结果:

设计模式---模板方法(Template Method)模式

4. 总结

  • 如果使用模板方法模式,当我们在模板方法里发现bug时,只需要修改模板方法就能解决问题。
  • 在子类实现父类中声明的抽象方法时,必须要理解这行方法被调用的时机。
  • 使用父类类型的变量保存子类实例的有点:即使不用instanceof等指定子类的类型,程序也能正常运行。
  • 父类和子类相互协作支撑了整个程序。在抽象类阶段确定处理流程很重要,如果把过多的方法的具体实现放在父类,会降低子类的灵活性;反之,如果子类需要实现的方法过多,就会造成子类臃肿并且增加了出现bug的几率。

继续阅读