第六章 6.2 模板方法模式

分类:01_设计模式

标签:

6.2.1 模板方法模式介绍

模板方法模式(template method pattern)原始定义是:在操作中定义算法的框架,将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。

模板方法中的算法可以理解为广义上的业务逻辑,并不是特指某一个实际的算法.定义中所说的算法的框架就是模板, 包含算法框架的方法就是模板方法.

例如: 我们去医院看病一般要经过以下4个流程:挂号、取号、排队、医生问诊等,其中挂号、 取号 、排队对每个病人是一样的,可以在父类中实现,但是具体医生如何根据病情开药每个人都是不一样的,所以开药这个操作可以延迟到子类中实现。

108.jpg

模板方法模式是一种基于继承的代码复用技术,它是一种类行为模式. 模板方法模式其结构中只存在父类与子类之间的继承关系.

模板方法的作用主要是提高程序的复用性和扩展性:

6.2.2 模板方法模式原理

模板方法模式的定位很清楚,就是为了解决算法框架这类特定的问题,同时明确表示需要使用继承的结构。

109.jpg

模板方法(Template Method)模式包含以下主要角色:

抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

6.2.3 模板方法模式实现

UML类图对应的代码实现


/**
* 抽象父类
* @author spikeCong
* @date 2022/10/12
**/
public abstract class AbstractClassTemplate {

   void step1(String key){
       System.out.println("在模板类中 -> 执行步骤1");
       if(step2(key)){
           step3();
       }else{
           step4();
       }

       step5();
   }

   boolean step2(String key){
       System.out.println("在模板类中 -> 执行步骤2");
       if("x".equals(key)){
           return true;
       }
       return false;
   }

   abstract void step3();
   abstract void step4();

   void step5(){
       System.out.println("在模板类中 -> 执行步骤5");
   }

   void run(String key){
       step1(key);
   }

}

public class ConcreteClassA extends AbstractClassTemplate{


   @Override
   void step3() {
       System.out.println("在子类A中 -> 执行步骤 3");
   }

   @Override
   void step4() {
       System.out.println("在子类A中 -> 执行步骤 4");
   }
}

public class ConcreteClassB extends AbstractClassTemplate {

   @Override
   void step3() {
       System.out.println("在子类B中 -> 执行步骤 3");
   }

   @Override
   void step4() {
       System.out.println("在子类B中 -> 执行步骤 4");
   }
}

public class Test01 {

   public static void main(String[] args) {
       AbstractClassTemplate concreteClassA = new ConcreteClassA();
       concreteClassA.run("");

       System.out.println("===========");

       AbstractClassTemplate concreteClassB = new ConcreteClassB();
       concreteClassB.run("x");
   }
}

// 输出结果
在模板类中 -> 执行步骤1
在模板类中 -> 执行步骤2
在子类A中 -> 执行步骤 4
在模板类中 -> 执行步骤5
===========
在模板类中 -> 执行步骤1
在模板类中 -> 执行步骤2
在子类B中 -> 执行步骤 3
在模板类中 -> 执行步骤5

6.2.4 模板方法模式应用实例

P2P公司的借款系统中有一个利息计算模块,利息的计算流程是这样的:

  1. 用户登录系统,登录时需要输入账号密码,如果登录失败(比如用户密码错误),系统需要给出提示

  2. 如果用户登录成功,则根据用户的借款的类型不同,使用不同的利息计算方式进行计算

  3. 系统需要显示利息.


/**
* 账户抽象类
* @author spikeCong
* @date 2022/10/12
**/
public abstract class Account {

   //step1 具体方法-验证用户信息是否正确
   public boolean validate(String account,String password){
       System.out.println("账号: " + account + ",密码: " + password);
       if(account.equalsIgnoreCase("tom") &&
       password.equalsIgnoreCase("123456")){
           return true;
       }else{
           return false;
       }
   }

   //step2 抽象方法-计算利息
   public abstract void calculate();

   //step3 具体方法-显示利息
   public void display(){
       System.out.println("显示利息!");
   }

   //模板方法
   public void handle(String account,String password){
       if(!validate(account,password)){
           System.out.println("账户或密码错误!!");
           return;
       }
       calculate();
       display();
   }
}


/**
* 借款一个月
* @author spikeCong
* @date 2022/10/12
**/
public class LoanOneMonth extends Account{

   @Override
   public void calculate() {
       System.out.println("借款周期30天,利率为10%!");
   }
}

/**
* 借款七天
* @author spikeCong
* @date 2022/10/12
**/
public class LoanSevenDays extends Account{

   @Override
   public void calculate() {
       System.out.println("借款周期7天,无利息!仅收取贷款金额1%的服务费!");
   }

   @Override
   public void display() {
       System.out.println("七日内借款无利息!");
   }

}


public class Client {

   public static void main(String[] args) {

       Account a1 = new LoanSevenDays();
       a1.handle("tom","12345");

       System.out.println("==========================");

       Account a2 = new LoanOneMonth();
       a2.handle("tom","123456");
   }
}


6.2.5 模板方法模式总结

优点:

缺点:

模板方法模式的使用场景一般有:


修改内容