Java中的模板模式说明与实现

 更新时间:2023年10月09日 08:48:19   作者:靖节先生  
这篇文章主要介绍了Java中的模板模式说明与实现,模板方法模式,又叫模板模式,在一个抽象类公开定义了执行它的方法的模板,它的子类可以更需要重写方法实现,但可以成为典型类中定义的方式进行,需要的朋友可以参考下

1. 模板模式概述

1.1 模板模式介绍

  • 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern), 在一个抽象类公开定义了执行它的方法的模板。它的子类可以更需要重写方法实现,但可以成为典型类中定义的方式进行。
  • 简单说,模板方法模式定义了一个操作中的算法的核心定义,而将一些步骤迟缓到子类中,模仿子类可以不改变一一个算法的结构,就可以重新定义该算法的部分特定步骤。
  • 这些类型的设计模式属于行为型模式。

模板模式适用于通用步骤的操作,比如做菜,不管你是西红柿炒鸡蛋,还是土豆炖牛肉实现步骤都是一样的,备料,做菜,上菜。 再比如投放系统,不管你是投放巨量引擎,广点通还是百度,前期工作实现步骤也都是一样的,配置物料信息,构建投放对象,投放广告。

1.2 模板模式类图

在这里插入图片描述

对原理类图的说明-即(模板方法模式的角色及职责)

1.AbstractClass 抽象类, 类中实现了模板方法(template),定义了算法的骨架,具体子类需要去实现 其它的抽象方法。

2.ConcreteClass 实现抽象方法, 以完成算法中特点子类的步骤。

1.3 模板方法模式的注意事项和细节

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

2. 模板模式实现

模板模式实现案例采用三种方式: 第一案例是做菜,无论做什么菜都是这三个步骤,备料,做菜,上菜,但是三个步骤都不相同,模板定义步骤流程,通过不同的子类继承抽象模板实现模板设计模式。

第二个案例是银行办理业务,无论办理什么业务都是取号,办理业务,评价。这里取号与评价都是相同的,各个子类只需要处理不同业务即可,通过不同的子类继承抽象模板实现模板设计模式。

第三个案例是银行办理业务的Java8函数式编程消费者模式Consumer模式改造,原理相同。

2.1 做菜模板模式

DishEggsWithTomato

package com.zrj.design.template.dish;
/**
 * 西红柿炒鸡蛋
 *
 * @author zrj
 * @since 2022/2/8
 */
public class DishEggsWithTomato extends DishTemplate {
    @Override
    public void preparation() {
        System.out.println("准备西红柿鸡蛋...");
    }
    @Override
    public void doing() {
        System.out.println("开始炒西红柿鸡蛋...");
    }
    @Override
    public void carriedDishes() {
        System.out.println("西红柿鸡蛋装盘...");
    }
}

DishOnionWithTofu

package com.zrj.design.template.dish;
/**
 * 小葱拌豆腐
 *
 * @author zrj
 * @since 2022/2/8
 */
public class DishOnionWithTofu extends DishTemplate {
    @Override
    public void preparation() {
        System.out.println("准备小葱豆腐...");
    }
    @Override
    public void doing() {
        System.out.println("开始炒小葱拌豆腐...");
    }
    @Override
    public void carriedDishes() {
        System.out.println("小葱拌豆腐装盘...");
    }
}

DishTemplate

package com.zrj.design.template.dish;
/**
 * 做菜模板类
 * 用于定义做菜的执行步骤,所有菜都可以按照这种方式做菜
 *
 * @author zrj
 * @since 2022/2/8
 */
public abstract class DishTemplate {
    /**
     * 做菜执行步骤
     */
    public final void doDish() {
        this.preparation();
        this.doing();
        this.carriedDishes();
    }
    /**
     * 备料
     */
    public abstract void preparation();
    /**
     * 做菜
     */
    public abstract void doing();
    /**
     * 上菜
     */
    public abstract void carriedDishes();
}

DishTemplateTest

package com.zrj.design.template.dish;
import org.junit.Test;
/**
 * 模板模式
 * 抽象父类定义方法模板,子类自定义实现方式。
 * 优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。
 * 缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
 * 使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。
 * 注意事项:为防止恶意操作,一般模板方法都加上 final 关键词。
 *
 * 使用场景很多,只要有相同的执行逻辑,或者重要的复杂的方法,都可以交给父类管理。
 * 比如开发XX系统步骤都是一样的,立项,需求,开发,测试,上线。
 *
 * @author zrj
 * @since 2022/2/8
 */
public class DishTemplateTest {
    @Test
    public void templateTest() {
        System.out.println("----------西红柿炒鸡蛋----------");
        DishTemplate eggsWithTomato = new DishEggsWithTomato();
        eggsWithTomato.doDish();
        System.out.println("----------小葱拌豆腐----------");
        DishTemplate onionWithTofu = new DishOnionWithTofu();
        onionWithTofu.doDish();
    }
}

2.2 银行办理业务模板模式

BankBusinessHandler

package com.zrj.design.template.bank;
import cn.hutool.core.util.RandomUtil;
/**
 * 模板方法设计模式的抽象类
 * 模板设计模式主要用来处理相同处理流程中的不同点,例如银行办理业务,无论什么业务,首先需要取号,其次处理业务,然后评价不同之处在于处理不同的业务使用不同的方式。
 * BankBusinessHandler作为抽象模板
 * BankSaveMoneyHandler作为存钱业务处理类,继承抽象模板BankBusinessHandler
 * BankDrawMoneyHandler作为理财业务处理类,继承抽象模板BankBusinessHandler
 *
 * @author zrj
 * @since 2022/2/8
 **/
public abstract class BankBusinessHandler {
    /**
     * 模板方法,执行器
     */
    public final void execute() {
        getNumber();
        handle();
        judge();
    }
    /**
     * 取号
     */
    private void getNumber() {
        System.out.println("取号:" + RandomUtil.randomNumbers(8));
    }
    /**
     * 办理业务
     */
    public abstract void handle();
    /**
     * 评价
     */
    private void judge() {
        System.out.println("评价:五星好评!");
    }
}

BankBusinessHandlerTest

package com.zrj.design.template.bank;
/**
 * 模板方法测试类
 *
 * @author zrj
 * @since 2022/2/8
 **/
public class BankBusinessHandlerTest {
    public static void main(String[] args) {
        //存钱业务处理
        BankSaveMoneyHandler bankSaveMoneyHandler = new BankSaveMoneyHandler();
        bankSaveMoneyHandler.execute();
        System.out.println("------------------------------");
        //理财业务处理
        BankDrawMoneyHandler bankDrawMoneyHandler = new BankDrawMoneyHandler();
        bankDrawMoneyHandler.execute();
    }
}

BankDrawMoneyHandler

package com.zrj.design.template.bank;
/**
 * 理财业务
 *
 * @author zrj
 * @since 2022/2/8
 **/
public class BankDrawMoneyHandler extends BankBusinessHandler {
    /**
     * 办理业务
     */
    @Override
    public void handle() {
        System.out.println("理财:2000$");
    }
}

BankSaveMoneyHandler

package com.zrj.design.template.bank;
/**
 * 存钱业务
 *
 * @author zrj
 * @since 2022/2/8
 **/
public class BankSaveMoneyHandler extends BankBusinessHandler {
    /**
     * 办理业务
     */
    @Override
    public void handle() {
        System.out.println("存钱:1000$");
    }
}

2.3 银行办理业务函数式编程改造

BankBusinessHandlerCustomer

package com.zrj.design.template.customer;
import cn.hutool.core.util.RandomUtil;
import java.math.BigDecimal;
import java.util.function.Consumer;
/**
 * 模板设计模式的抽象类
 * Java8函数式编程消费者模式Customer实现模板设计模式
 *
 * @author zrj
 * @since 2022/2/8
 **/
public class BankBusinessHandlerCustomer {
    /**
     * 存钱
     */
    public void save(BigDecimal amount) {
        execute(a -> System.out.println("存钱:" + amount));
    }
    /**
     * 理财
     */
    public void draw(BigDecimal amount) {
        execute(a -> System.out.println("理财:" + amount));
    }
    /**
     * 模板方法,执行器
     */
    public void execute(Consumer<BigDecimal> consumer) {
        getNumber();
        consumer.accept(null);
        judge();
    }
    /**
     * 取号
     */
    private void getNumber() {
        System.out.println("取号:" + RandomUtil.randomNumbers(8));
    }
    /**
     * 评价
     */
    private void judge() {
        System.out.println("评价:五星好评!");
    }
}

BankBusinessHandlerCustomerTest

package com.zrj.design.template.customer;
import java.math.BigDecimal;
/**
 * @author zrj
 * @since 2022/2/8
 **/
public class BankBusinessHandlerCustomerTest {
    public static void main(String[] args) {
        //构建银行业务处理对象
        BankBusinessHandlerCustomer businessHandler = new BankBusinessHandlerCustomer();
        //存钱业务处理
        businessHandler.save(new BigDecimal("3000"));
        System.out.println("------------------------------");
        //理财业务处理
        businessHandler.draw(new BigDecimal("6000"));
    }
}

到此这篇关于Java中的模板模式说明与实现的文章就介绍到这了,更多相关Java模板模式实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 自定义一个异常类模板的简单实例

    自定义一个异常类模板的简单实例

    下面小编就为大家带来一篇自定义一个异常类模板的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 如何使用SpringBootCondition更自由地定义条件化配置

    如何使用SpringBootCondition更自由地定义条件化配置

    这篇文章主要介绍了如何使用SpringBootCondition更自由地定义条件化配置,帮助大家更好的理解和学习使用springboot框架,感兴趣的朋友可以了解下
    2021-04-04
  • Java使用条件语句和循环结构确定控制流(实例)

    Java使用条件语句和循环结构确定控制流(实例)

    下面小编就为大家带来一篇Java使用条件语句和循环结构确定控制流(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • SpringBoot从繁至简的框架基础教程

    SpringBoot从繁至简的框架基础教程

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置
    2022-10-10
  • 详解SpringBoot初始教程之Tomcat、Https配置以及Jetty优化

    详解SpringBoot初始教程之Tomcat、Https配置以及Jetty优化

    本篇文章主要介绍了详解SpringBoot初始教程之Tomcat、Https配置以及Jetty优化,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • Java之网络编程案例讲解

    Java之网络编程案例讲解

    这篇文章主要介绍了Java之网络编程案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Java编程调用微信接口实现图文信息推送功能

    Java编程调用微信接口实现图文信息推送功能

    这篇文章主要介绍了Java编程调用微信接口实现图文信息等推送功能,涉及java微信图文信息推送接口调用及相关文件、字符串编码转换相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • Java如何利用状态模式(state pattern)替代if else

    Java如何利用状态模式(state pattern)替代if else

    这篇文章主要给大家介绍了关于Java如何利用状态模式(state pattern)替代if else的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java程序员常犯的五个错误

    Java程序员常犯的五个错误

    这篇文章总结以前经验针对java编程的一些习惯,给出一些关于java编程的建议: 当你开始成为一个程序员的时候,在编程的时候很容易陷入下面所述的一些坏习惯,下面把Java程序员常犯的五个错误整理如下,需要的朋友可以参考下
    2015-07-07
  • 完美解决docx4j变量替换的问题

    完美解决docx4j变量替换的问题

    这篇文章主要介绍了完美解决docx4j变量替换的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论