深入浅出设计模式 - 模板方法模式

简介: 深入浅出设计模式 - 模板方法模式

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

1687876515174.jpg

1、什么是模板方法模式

模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,将一些步骤的具体实现延迟到子类中,使得子类可以改变算法的某些特定步骤,而不改变算法的结构。

模板方法模式的核心思想是:定义一个抽象类,其中包含一个模板方法,该方法中定义了算法的骨架,然后将一些步骤的实现交给子类去完成。子类可以重写这些步骤,从而改变算法的具体实现,但是算法的结构不会改变。

2、模板方法模式的优缺点

模板方法模式的优点包括:

  1. 将算法的骨架和具体实现分离,提高了代码的复用性和可维护性。

  2. 子类可以灵活地改变算法的某些步骤,从而实现不同的功能。

  3. 父类可以控制子类的执行顺序,保证算法的正确性。

模板方法模式的缺点包括:

  1. 父类和子类之间的耦合度较高,一旦父类的代码发生改变,可能会影响到子类的实现。

  2. 可能会导致类的数量增加,增加代码的复杂度。

    3、模板方法模式的应用场景

    模板方法模式适用于以下场景:

  3. 算法的整体步骤固定,但某些步骤的具体实现可以在子类中改变。

  4. 避免代码重复,将相同的代码抽象到父类中,子类只需要实现特定的代码即可。

  5. 父类需要控制子类的执行顺序,从而保证算法的正确性。

具体的应用场景有:

  1. 框架设计:框架中通常都会定义一些模板方法,子类通过实现特定的方法来完成框架的功能。

  2. 数据库访问:在访问数据库时,通常都需要进行连接、查询、关闭等操作,这些操作的顺序是固定的,但是具体的实现可以有所不同。

  3. 网络编程:在网络编程中,通常需要先建立连接、发送数据、接收数据等操作,这些操作的顺序是固定的,但是具体的实现可以有所不同。

  4. 面向对象设计:在面向对象设计中,通常会使用模板方法模式来实现一些通用的算法,如排序算法、搜索算法等。

  5. 游戏开发:在游戏开发中,通常需要实现一些通用的功能,如角色移动、攻击、防御等,这些功能的实现可以使用模板方法模式。

    4、模板方法模式的结构

模板方法模式是一种行为设计模式,它定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。这种模式属于行为型模式。

模板方法模式的结构包括以下几个部分:

  1. 抽象类(AbstractClass):定义了算法的骨架,包含了若干个抽象方法,这些方法由子类实现。

  2. 具体类(ConcreteClass):实现了抽象类中定义的抽象方法,完成算法中的具体步骤。

  3. 钩子方法(Hook Method):在抽象类中定义的方法,子类可以选择性地覆盖它们,以改变算法的行为。

  4. 模板方法(Template Method):定义了算法的骨架,包含了一系列调用抽象方法和钩子方法的步骤,子类不能修改它的行为。

    模板方法模式的核心思想是将算法的具体实现交给子类来完成,从而实现代码的复用和扩展。

    5、模板方法模式的代码案例

package com.pany.camp.design.principle.template;

/**
 *
 * @description:  抽象类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 22:42
 */
public abstract class CaffeineBeverage {
   
   

    final void prepareRecipe() {
   
   
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
   
   
            addCondiments();
        }
    }

    void boilWater() {
   
   
        System.out.println("Boiling water");
    }

    void pourInCup() {
   
   
        System.out.println("Pouring into cup");
    }

    abstract void brew();

    abstract void addCondiments();

    boolean customerWantsCondiments() {
   
   
        return true;
    }
}
package com.pany.camp.design.principle.template;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @description: 咖啡
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 22:42
 */
class Coffee extends CaffeineBeverage {
   
   
    void brew() {
   
   
        System.out.println("Dripping coffee through filter");
    }

    void addCondiments() {
   
   
        System.out.println("Adding sugar and milk");
    }

    boolean customerWantsCondiments() {
   
   
        String answer = getUserInput();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput() {
   
   
        String answer = null;
        System.out.print("Would you like sugar and milk with your coffee? (y/n) ");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
   
   
            answer = in.readLine();
        } catch (IOException e) {
   
   
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
   
   
            return "no";
        }
        return answer;
    }
}
package com.pany.camp.design.principle.template;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @description: 茶
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 22:43
 */
class Tea extends CaffeineBeverage {
   
   
    void brew() {
   
   
        System.out.println("Steeping the tea");
    }

    void addCondiments() {
   
   
        System.out.println("Adding lemon");
    }

    boolean customerWantsCondiments() {
   
   
        String answer = getUserInput();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput() {
   
   
        String answer = null;
        System.out.print("Would you like lemon with your tea? (y/n) ");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
   
   
            answer = in.readLine();
        } catch (IOException e) {
   
   
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
   
   
            return "no";
        }
        return answer;
    }
}
package com.pany.camp.design.principle.template;

/**
 *
 * @description:  客户端
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 22:43
 */
public class Client {
   
   
    public static void main(String[] args) {
   
   
        CaffeineBeverage coffee = new Coffee();
        CaffeineBeverage tea = new Tea();

        System.out.println("Making coffee...");
        coffee.prepareRecipe();

        System.out.println("\nMaking tea...");
        tea.prepareRecipe();
    }
}

CaffeineBeverage 是抽象类,定义了制作咖啡因饮料的模板方法 prepareRecipe() ,以及一些基本方法 boilWater() 和 pourInCup() 。 CaffeineBeverage 还定义了两个抽象方法 brew() 和 addCondiments() ,由子类实现。

Coffee 和 Tea 是具体类,实现了 brew() 和 addCondiments() 方法,以及 customerWantsCondiments() 钩子方法,可以根据客户的需求选择是否添加调料。

在 main 函数中,我们创建了 Coffee 和 Tea 对象,并调用它们的 prepareRecipe() 方法,输出了制作咖啡和茶的过程。

输出结果如下:

Making coffee...
Boiling water
Dripping coffee through filter
Pouring into cup
Would you like sugar and milk with your coffee? (y/n) y
Adding sugar and milk

Making tea...
Boiling water
Steeping the tea
Pouring into cup
Would you like lemon with your tea? (y/n) y
Adding lemon

Process finished with exit code 0

1686494501743.jpg

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊

1687869804912.jpg

目录
相关文章
|
5月前
|
设计模式 算法
二十三种设计模式全面解析-深入解析模板方法模式的奇妙世界
二十三种设计模式全面解析-深入解析模板方法模式的奇妙世界
|
12月前
|
设计模式 存储 算法
行为型设计模式02-模板方法模式
行为型设计模式02-模板方法模式
44 0
|
12月前
|
设计模式 算法
设计模式9 - 模板方法模式【Template Method Pattern】
设计模式9 - 模板方法模式【Template Method Pattern】
34 0
|
12月前
|
设计模式 算法 Java
设计模式~模板方法模式(Template method)-10
目录 (1)优点: (2)缺点: (3)使用场景: (4)注意事项: (5)应用实例: (6)Servlet Api &
51 0
|
7天前
|
设计模式 算法 Java
Java设计模式-模板方法模式(14)
Java设计模式-模板方法模式(14)
|
3月前
|
设计模式 JavaScript 算法
js设计模式【详解】—— 模板方法模式
js设计模式【详解】—— 模板方法模式
41 6
|
4月前
|
设计模式 算法 关系型数据库
设计模式第七讲-外观模式、适配器模式、模板方法模式详解
系统要求所有的数据库帮助类必须实现ISqlHelp接口,面向该接口编程,如SQLServerHelp类。 此时第三方提供了一个新的MySql的帮助类(假设是dll,不能修改),它的编程规范和ISqlHelp不兼容,这个时候就需要引入适配器类,使二者能相互兼容。
163 0
|
5月前
|
设计模式 算法 Java
Java 设计模式:深入模板方法模式的原理与应用
【4月更文挑战第27天】模板方法模式是一种行为设计模式,主要用于定义一个操作中的算法的框架,允许子类在不改变算法结构的情况下重定义算法的某些特定步骤。
47 1
|
5月前
|
设计模式 Go
[设计模式 Go实现] 行为型~模板方法模式
[设计模式 Go实现] 行为型~模板方法模式
|
5月前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式