常见设计模式之模板模式

本文介绍了设计模式中的模板模式,通过一个银行办理业务的场景,展示了如何使用模板模式来封装不变的业务流程,并允许子类在不改变整体流程的情况下重定义具体步骤。在银行业务中,如存钱、取钱、办卡等不同业务虽然步骤相同但细节不同,模板模式能够有效地抽象出共性部分,提高代码复用性和可扩展性。
摘要由CSDN通过智能技术生成

常见设计模式之模板模式

1、什么是模板模式

一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按照需要重写方法实现,但调用将以抽象类中定义的方式进行,这种类型的设计模式属于行为模式

2、介绍
  • 应用场景:做一件事情的方法有很多,但做这件事的步骤都可以归纳为几步,这个时候就可以用模板模式。
  • 作用:在模板类中定义做事的步骤,将多种实现做事的细节在子类中实现。即:定义一个操作中的算法的骨架(模板函数),而将一些步骤延迟到子类中(基本函数)。模板模式使得子类可以不改变一个算法的结构(模板函数),即可重定义该算法的实现方式(基本函数)。
  • 应用实例:AQS(AbstractQueuedSynchronizer)就是基于模板模式来实现,提供一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,AQS模板为ReentedLocK、CountDownLatch、Semaphore提供了优秀的解决方案。
  • 优点:1、封装不变部分,扩展可变部分 2、提取公共代码,便于维护 3、行为父类控制,子类实现
  • 缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
3、实现

在这里描述一个场景,用户去银行办理业务的流程(排队取号 -> 到柜台办理业务 -> 给业务员打分)。但是不同的用户去办理的业务有可能不一样,比如张三去存钱,李四去取钱,王五去办卡……

基于这种场景下,就可以使用模板模式,先创建一个抽象类,定义流程中的几个步骤,代码如下:

@Slf4j
abstract class AbstractBankService {

    /**
     * 1、排队取号
     *
     * @param name 姓名
     * @return true or false
     */
    protected Boolean queueUp(String name) {
        log.info("用户{}排队取号", name);
        return true;
    }

    /**
     * 2、到柜台办理业务
     *
     * @param name 姓名
     */
    protected void handleBusiness(String name) {
        log.info("用户{}办理业务", name);
    }

    /**
     * 3、为服务打分
     *
     * @param name 姓名
     */
    protected void score(String name) {
        log.info("用户{}为服务打分", name);
    }
    
    /**
     * 银行业务流程
     * 
     * @param name 姓名
     */
    public final void bankBusiness(String name) {
        log.info("用户{}进入银行", name);
        if (this.queueUp(name)) {
            this.handleBusiness(name);
        }
        this.score(name);
        log.info("用户{}离开银行", name);
    }

}

注:抽象类中的方法 queueUp()、handleBusiness()、score() 都是对应上面提到的基本函数,基本函数是可拓展的;bankBusiness() 对应模板函数,模板函数是不可变的,需要用 final 修饰

然后可以根据具体业务去创建不同的类去继承这个抽象类,然后重写父类方法实现具体业务逻辑,代码如下:

@Slf4j
public class TransferService extends AbstractBankService {

    @Override
    protected void handleBusiness(String name) {
        log.info("用户{}办理转账业务", name);
    }

    public void service(String name) {
        bankBusiness(name);
    }

    public static void main(String[] args) {
        TransferService transferService = new TransferService();
        transferService.service("xiaohu");
    }

}

执行 TransferServicemain 方法,打印结果如下:

22:20:07.554 [main] INFO cn.enjoyedu.springboot.es.highlevel.designMode.template.AbstractBankService - 用户:xiaohu进入银行
22:20:07.560 [main] INFO cn.enjoyedu.springboot.es.highlevel.designMode.template.AbstractBankService - 用户:xiaohu排队取号
22:20:07.560 [main] INFO cn.enjoyedu.springboot.es.highlevel.designMode.template.TransferService - 用户:xiaohu办理转账业务
22:20:07.560 [main] INFO cn.enjoyedu.springboot.es.highlevel.designMode.template.AbstractBankService - 用户:xiaohu为服务打分
22:20:07.561 [main] INFO cn.enjoyedu.springboot.es.highlevel.designMode.template.AbstractBankService - 用户:xiaohu离开银行
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值