【设计模式】Java设计模式——模板方法模式(Template Pattern)

1. 介绍

1.1 定义

  • 模板方法模式(Template Pattern),又叫模板模式,它属于行为型模式
  • 模板方法模式定义一个模板结构,将具体内容延迟到子类去实现

1.2 作用

  • 使得子类可以在不改变一个模板的结构的前提下重新定义该模板的某些特定步骤

2. 模式结构

2.1 UML类图

在这里插入图片描述

2.2 模式组成

  • 模板方法(Template Method):模板方法定义了模板的特定步骤
  • 抽象方法(Abstract Method):抽象方法由抽象类声明,由其子类实现,使用abstract关键字标识
  • 具体方法(Concrete Method):具体方法由抽象类声明并实现,子类不可修改,使用final关键字标识
  • 钩子方法(Hook Method):钩子方法由抽象类声明,子类可以重写

3. 代码实例

3.1 背景

申请虚拟机需要分配ip,网卡,磁盘等,闲置时需要进行删除,每个操作的请求体各不相同,但是流程是一致的,比如参数校验,资源评估,生成任务id,提交任务等,这个时候定义一个模板类相当合适。

3.2 应用

代码主要为了说明模板方法模式的大致用法,非常简化,仅供参考

  • 步骤1 定义request类(公共参数可以抽成父类)

    public class AbstractVmRequest {
    
        /**
         * create/delete
         */
        private String action;
    
        private String operator;
    
        private String jobId;
    }
    
    public class VmIpRequest extends AbstractVmRequest {
    
        private List<CreateIpVO> createIpVOList;
    
        private List<DeleteIpVO> deleteIpVOList;
    }
    
    public class VmVolumeRequest extends AbstractVmRequest {
    
        private List<CreateVolumeVO> createVolumeVOList;
    
        private List<DeleteVolumeVO> deleteVolumeVOList;
    }
    
  • 步骤2 定义抽象模板类

    public abstract class AbstractVmRegister {
    
        public final String VmRegister(AbstractVmRequest request) throws Exception {
            // 参数校验
            verifyParameter(request);
    
            // 资源评估
            evaluateResource(request);
    
            // 生成任务id
            String jobId = generateJobId(request);
    
            // 提交并执行任务
            submitVmJob(request);
            return jobId;
        }
    
        // 抽象方法,由子类实现
        protected abstract void verifyParameter(AbstractVmRequest request) throws Exception;
    
        // 钩子方法,父类已实现,子类也可以重写
        protected void evaluateResource(AbstractVmRequest request) {
            // 当前资源充足,不进行资源评估
            System.out.println("skip evaluate resource");
        }
    
        // 具体方法,父类已实现,子类无需实现
        final String generateJobId(AbstractVmRequest request) {
            String jobId = UUID.randomUUID().toString();
            request.setJobId(jobId);
            return jobId;
        }
    
        // 抽象方法,由子类实现
        protected abstract void submitVmJob(AbstractVmRequest request);
    }
    
  • 步骤3 定义实现类-ip

    public class VmIpCreateRegister extends AbstractVmRegister {
    
        @Override
        protected void verifyParameter(AbstractVmRequest request) throws Exception {
            VmIpRequest vmIpRequest;
            if (request instanceof VmIpRequest) {
                vmIpRequest = (VmIpRequest) request;
            } else {
                throw new Exception("The bean type does not support ip create");
            }
            if (CollectionUtils.isEmpty(vmIpRequest.getCreateIpVOList())) {
                throw new Exception("createIpVOList can not be empty");
            }
        }
    
        @Override
        protected void submitVmJob(AbstractVmRequest request) {
            // 调用service方法执行操作
            // ipService.execute()
            System.out.println(String.format("submit ip create job, jobId: %s", request.getJobId()));
        }
    }
    
  • 步骤4 定义实现类-volume

    public class VmVolumeCreateRegister extends AbstractVmRegister {
    
        @Override
        protected void verifyParameter(AbstractVmRequest request) throws Exception {
            VmVolumeRequest vmVolumeRequest;
            if (request instanceof VmVolumeRequest) {
                vmVolumeRequest = (VmVolumeRequest) request;
            } else {
                throw new Exception("The bean type does not support volume create");
            }
            if (CollectionUtils.isEmpty(vmVolumeRequest.getCreateVolumeVOList())) {
                throw new Exception("createVolumeVOList can not be empty");
            }
        }
    
        @Override
        protected void submitVmJob(AbstractVmRequest request) {
            // 调用service方法执行操作
            // volumeService.execute()
            System.out.println(String.format("submit volume create job, jobId: %s", request.getJobId()));
        }
    }
    
  • 外部调用(这边推荐使用策略模式,提前将实现类放在map里,调用的时候直接通过map获取实现类)

    public static void main(String[] args) throws Exception {
    
            // 填充参数模拟api调用
            VmVolumeRequest vmVolumeRequest = new VmVolumeRequest();
            // action可以写成枚举类
            vmVolumeRequest.setAction("create");
            vmVolumeRequest.setOperator("DustHeart");
            vmVolumeRequest.setCreateVolumeVOList(Collections.singletonList(new CreateVolumeVO()));
    
            VmVolumeCreateRegister vmVolumeCreateRegister = new VmVolumeCreateRegister();
            String jobId = vmVolumeCreateRegister.VmRegister(vmVolumeRequest);
            System.out.println(jobId);
        }
    

4. 优点

  • 提高代码复用性,将相同处理逻辑的代码放在抽象父类中
  • 提高了拓展性,子类实现抽象父类的某些细节,有助于模板父类的扩展
  • 符合开闭原则,通过一个父类调用子类实现的操作,可以通过子类扩展增加新的行为

5. 缺点

  • 引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,系统会更加庞大
  • 模板方法主要通过继承实现,如果父类增加新的抽象方法,所有的子类都要修改一遍

6. 应用场景

  • 编排一个流程的固定步骤,实现某些步骤不变的部分,并将可变的步骤留给子类来实现,使得子类在步骤固定的情况下进行功能的不同实现和拓展
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值