你所向往的Java深处之23种设计模式之模板方法模式

模板方法模式

  • 基本介绍

    • 模板方法模式,又叫模板模式,在一个抽象类公开了执行它的方法的模板。他的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
    • 简单说,模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
    • 这些类型的设计模式属于行为型模式。
  • 原理类图

    • 在这里插入图片描述

    • 角色分析:

      • AbstractClass抽象类,实现了模板方法,定义了算法的骨架,具体子类需要去实现,其他的抽象方法operation2,3,4
      • ConcreteClaa实现抽象方法operation2,3,4,以完成算法中特点子类的步骤。
  • 代码示例:

    • 类图解析:

      • 在这里插入图片描述
    • //抽象类,表示豆浆
      public abstract class Doujiang {
          //模板方法,make,模板方法可以做成final,不让子类重写
          final void make(){
              select();
              addCondiments();
              soak();
              beat();
          }
          //选材料
          void select(){
              System.out.println("第一步:选择新鲜黄豆");
          }
          //添加不同的配料,抽象方法,子类具体实现
          abstract void addCondiments();
      
          //浸泡
          void soak(){
              System.out.println("第三步,黄豆和配料开始浸泡");
          }
      
          //
          void beat(){
              System.out.println("第四步:黄豆和配料放到豆浆机打碎");
          }
      }
      
      
      //红豆豆浆
      public class RedDoujiang extends Doujiang {
          @Override
          void addCondiments() {
              System.out.println("加入上好的红豆");
          }
      }
      
      //黄豆豆浆
      public class YellowDoujiang extends Doujiang {
      
          @Override
          void addCondiments() {
              System.out.println("加入上好的黄豆");
          }
      }
      
      public class Client {
          public static void main(String[] args) {
              System.out.println("制作红豆豆浆");
              Doujiang redDoujiang = new RedDoujiang();
              redDoujiang.make();
      
              System.out.println("制作黄豆豆浆");
              Doujiang yellowDoujiang = new YellowDoujiang();
              yellowDoujiang.make();
          }
      }
      
    • 在这里插入图片描述

  • 末模板方法模式中的钩子方法

    • 在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”。

    • 还用做上述做豆浆的例子,比如,我们还希望制作纯豆浆,不添加任何的配料呢么就是使用钩子方法对代码进行改进。

    • //抽象类,表示豆浆
      public abstract class Doujiang {
          //模板方法,make,模板方法可以做成final,不让子类重写
          final void make(){
              select();
              if(customerWantCondiments()){
                  addCondiments();
              }
      
              soak();
              beat();
          }
          //选材料
          void select(){
              System.out.println("第一步:选择新鲜黄豆");
          }
          //添加不同的配料,抽象方法,子类具体实现
          abstract void addCondiments();
      
          //浸泡
          void soak(){
              System.out.println("第三步,黄豆和配料开始浸泡");
          }
      
          //
          void beat(){
              System.out.println("第四步:黄豆和配料放到豆浆机打碎");
          }
          //钩子方法
          boolean customerWantCondiments(){
              return true;
          };
      }
      
      
      //红豆豆浆
      public class RedDoujiang extends Doujiang {
          @Override
          void addCondiments() {
              System.out.println("加入上好的红豆");
          }
      }
      
      //黄豆豆浆
      public class YellowDoujiang extends Doujiang {
      
          @Override
          void addCondiments() {
              System.out.println("加入上好的黄豆");
          }
      }
      
      public class PureDoujiang extends Doujiang{
          @Override
          void addCondiments() {
              //空实现
          }
      
          @Override
          boolean customerWantCondiments() {
              return false;
          }
      }
      
      public class Client {
          public static void main(String[] args) {
              System.out.println("制作红豆豆浆");
              Doujiang redDoujiang = new RedDoujiang();
              redDoujiang.make();
      
              System.out.println("制作黄豆豆浆");
              Doujiang yellowDoujiang = new YellowDoujiang();
              yellowDoujiang.make();
      
              System.out.println("制作纯豆浆");
              Doujiang pureDoujiang = new PureDoujiang();
              pureDoujiang.make();
          }
      }
      
    • 在这里插入图片描述

  • Spring框架的IOC容器底层用到模板方法模式。

  • 注意事项和细节

    • 基本思想:算法只存在于一个地方,也就是父类中,容易修改。需要修改算法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改。
    • 实现了最大化代码复用。父类的模板方法和已经实现的某些步骤会被子类继承而直接使用。
    • 即统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现。
    • 该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大。
    • 一般模板方法都加上final关键字,防止子类重写模板方法。
    • 模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤,这一系列的步骤基本相同,但其个别步骤在实现时可能不同,通常考虑用模板方法模式来处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值