23种设计模式——模板模式

简介: 模板模式需要注意抽象类与具体子类之间的协作。它用到了虚函数的多态性技术以及“不用调用我,让我来调用你”的反向控制技术。
今天我们来学习23种设计模式中的模板模式。模板模式需要注意抽象类与具体子类之间的协作。它用到了虚函数的多态性技术以及“不用调用我,让我来调用你”的反向控制技术。
概念:

模板模式是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

特点:

优点:

  1. 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
  2. 它在父类中提取了公共的部分代码,便于代码复用。
  3. 部分方法是由子类实现的,因此子类可以通过扩展方法增加相应的功能,符合开闭原则。

缺点:

  1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
类图分析:

模版模式类图.png

代码:

抽象类,豆浆

package cn.ppdxzz.template;

/**
 * description:抽象类,豆浆
 * @author: PeiChen JavaAnything
 */
public abstract class BaseSoyMilk {
    /**
     * 模板方法,修饰符设置成 final,不允许子类覆盖
     */
    final void make() {
        select();
        addCondiments();
        soak();
        beat();
    }

    /**
     * 1. 挑选材料
     */
    void select() {
        System.out.println("第一步:挑选新鲜的食材黄豆...");
    }

    /**
     * 2. 抽象方法,添加不同的食材,子类具体实现
     */
    abstract void addCondiments();

    /**
     * 3. 浸泡食材
     */
    void soak() {
        System.out.println("第三步:黄豆和配料开始浸泡...");
    }

    /**
     * 4. 打碎食材
     */
    void beat() {
        System.out.println("第四步:黄豆和配料放豆浆机里打碎。");
    }
}

红豆牛奶

package cn.ppdxzz.template;

/**
 * description:红豆牛奶
 * @author: PeiChen JavaAnything
 */
public class RedBeanSoyMilk extends BaseSoyMilk {
    @Override
    void addCondiments() {
        System.out.println("第二步:加入红豆...");
    }
}

花生牛奶

package cn.ppdxzz.template;

/**
 * description:花生牛奶
 * @author: PeiChen JavaAnything
 */
public class PeanutSoyMilk extends BaseSoyMilk {
    @Override
    void addCondiments() {
        System.out.println("第二步:加入花生...");
    }
}

模板模式客户端

package cn.ppdxzz.template;

/**
 * description:模板模式客户端
 * @author: PeiChen JavaAnything
 */
public class Client {
    public static void main(String[] args) {
        System.out.println("---制作红豆豆浆---");
        BaseSoyMilk redBeanSoyMilk = new RedBeanSoyMilk();
        redBeanSoyMilk.make();
        System.out.println("---制作花生豆浆---");
        BaseSoyMilk peanutSoyMilk = new PeanutSoyMilk();
        peanutSoyMilk.make();
    }
}

运行结果:

模版模式运行结果.png

总结:
  1. 有多个子类共有的方法,且逻辑相同时,可以考虑使用模板模式。
  2. 重要的、复杂的方法,可以考虑作为模板方法。
  3. 为防止恶意操作,一般模板方法都加上 final 关键词。
Spring 的 IoC 容器在初始化时就是用到了模板模式,需要深入了解的同学可以剖析下源码,自己研究一下。
目录
相关文章
|
1月前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
22 0
|
1月前
|
设计模式 开发者
探讨常见设计模式 - 工厂方法模式的最佳实践和潜在的实施问题
【4月更文挑战第7天】工厂方法模式是创建型设计模式,提供了一种在不指定具体类情况下创建对象的方式。它定义创建对象的接口,允许子类决定实例化哪个类,从而解耦对象的创建和使用。最佳实践包括明确接口、封装创建逻辑、提供扩展点和避免过度使用。然而,过度工程、违反开闭原则、性能影响和依赖管理是可能的问题。通过权衡利弊并遵循最佳实践,工厂方法模式能在适当场景下提升代码灵活性和可扩展性。
|
2月前
|
设计模式 算法 C++
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程(二)
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程
30 0
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
57 0
|
1月前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
1月前
|
设计模式 Java PHP
php设计模式--简单工厂模式(一)
php设计模式--简单工厂模式(一)
15 0
|
1天前
|
设计模式 JavaScript 前端开发
js设计模式-观察者模式与发布/订阅模式
观察者模式和发布/订阅模式是JavaScript中的两种设计模式,用于处理对象间的通信和事件处理。观察者模式中,一个主题对象状态改变会通知所有观察者。实现包括定义主题和观察者对象,以及在主题中添加、删除和通知观察者的功能。发布/订阅模式则引入事件管理器,允许发布者发布事件,订阅者通过订阅接收通知。
|
12天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
22 4
|
16天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
37 2
|
20天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式