模板方法设计模式

模板方法模式

简介:

  在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法的情况下,重新定义算法中的某些步骤。

要想明白模板方法模式首先我们将它分解为几个部分:
1. 抽象模板(抽象类):

  • 抽象方法,子类必须要实现的业务方法
  • 具体方法(final),必须不被重写的方法
  • 钩子方法,子类可重写,可不重写的方法
  • 模板方法b,按照一定的顺序引用的抽象方法、具体方法、钩子方法

2.具体模板(extends 抽象类):

  • 必须重写抽象模板中的抽象方法,根据自身特点实现具体的逻辑内容
  • 选择性的重写钩子方法
  • 其他自身的方法

3.测试

  • 得到某个具体模板的对象a
  • 对象a调用模板方法b获取模板。如:a.b

实例:

Head First 中模板方法中的举例:饮料店中生产饮料的过程方法

Tablecoffertea
步骤一把水煮沸把水煮沸
步骤二用沸水冲咖啡用沸水泡茶
步骤三倒入杯子中倒入杯子中
步骤四加入牛奶加入蜂蜜

抽象模板类

  我们将这四个步骤分别看做一种方法。由于步骤一和步骤三相同,我们将它设置为final方法,步骤二和步骤四有差异,我们只能定义抽象方法,由具体的子类实现相应的步骤.

  • 步骤一:public final toBoilWater(){};
  • 步骤二:abstract void make();
  • 步骤三:public final pourToCup(){};
  • 步骤四:abstract void add();
  • 步骤五:void hook(){};// 一个可重写,不可重写的钩子方法
    通过上面我们发现两种饮料生产过程几乎相同,我们将这个步骤顺序当做制作所有饮料的一个规范,将它封装到一个方法中,于是就有了模板方法。
  public final void getDrink(){
                      toBoilWater();
                      make();
                      pourToCup();
                      add();
            }

 至此抽象模板实现完毕


具体模板类

  1. 咖啡的制作
public class coffee extends cc {
     @Override
    void make() {
        System.out.println("倒入咖啡");
    }
    @Override
    void Add() {
        System.out.println("加入牛奶");
    }
}

2.茶的制作

public class tea extends cc {
    @Override
    void make() {
        System.out.println("我在泡茶");
    }
    @Override
    void Add() {
    System.out.println("我往里面加入了蜂蜜");
    }
}

实现:

public class text {
   public static void main(String[] arg) {
       coffee co=new coffee();
       co.getDrink();
       tea te=new tea();
       te.getDrink();
    }
}

  至此,一个模板方法模式算是实现了,但是我们 还没有使用过钩子方法


钩子方法:一个在抽象模板类中的具体方法,它可由适当的场合由子类重写或者不用重写。

  比如:我们要在制作咖啡饮料的时候,加入一个由用户选择的情况,用于只有在输入”y”时才可以继续制作咖啡。这里我们就需要使用钩子方法,由子类重写钩子方法,然后在调用子类中自身特有的方法来进行判定。

抽象模板类:
public abstract class cc {
      public final void getDrink(){
          toBoilWater();
          make();
          pourToCup();
          hook(); // 钩子方法
          Add();  
      }
      abstract  void make();
      abstract void Add();
    private void toBoilWater() {
      System.out.println("我在煮开水");  
    }
    private void pourToCup() {
      System.out.println("我在往杯子里面倒");   
    }
    public boolean hook(){ // 钩子方法,在子类实现具体的操作
        return true;
    }
}

具体模板类:咖啡
public class coffee extends cc {
     @Override
    void make() {
        System.out.println("倒入咖啡");
    }
    @Override
    void Add() {
        System.out.println("加入牛奶");
    }
    @Override
    public boolean hook() {  // 重写钩子方法
      String input=getInput(); // 钩子方法调用coffer类中的具体方法
        if (input.toLowerCase()=="y") { // 获取输入字符串的首字母
            return true;
        }else {
            return false;
        }
    }
    private String getInput() {
       String inputString=null;
       System.out.println("请输入是否要加入牛奶:yes or no");
       BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
       try {
        inputString=in.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
       if(inputString==null){
           return "no"; 
       }
        return inputString;
    }
}

  以上根据Head First 的理解下作的笔记,记忆力不好,刚接触编程,理解的很浅显,只当自己的自学笔记。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值