• [工作中的设计模式]模板模式


    一、模式解析

      准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意

      模板模式的关键点为:

      1、有一个父类,将整体业务逻辑和公用方法进行封装;

      2、父类将具体的有差异的业务定义为抽象方法;

      3、子类继承父类后,实现这些抽象方法,完成对自己业务流程的;

      4、子类不可以改变父类的整体业务逻辑流程;

      5、子类也可以覆盖父类中其他方法,实现定制化业务

    二、模式代码

    父类抽象类

    package template.patten;
    
    public abstract class AbstractTemplate {
        //业务逻辑执行
        public void templateMethod(){
            abstractMethod();
            hookMethod();
            concreteMethod();
        }
        //抽象方法,需要子类进行覆盖
        protected abstract void abstractMethod();
        
        //钩子方法,可以被子类覆盖
        protected void hookMethod() {
            System.out.println("我是模板中的hook方法");
        }
        //父类的具体方法,不可以被重写
        private void concreteMethod(){
            System.out.println("我是父类的具体方法不能被重写");
        }
    
    }

    子类实现具体业务逻辑

    package template.patten;
    
    public class ConcreteTemplate extends AbstractTemplate {
        
        @Override
        public void hookMethod() {
            System.out.println("先调用子类实现的hookmethod,然后再调用父类的方法");
            super.hookMethod();
        }
    
        @Override
        protected void abstractMethod() {
            System.out.println("抽象方法的具体实现");
        }
    }

    客户端调用

    package template.patten;
    
    public class Client {
        public static void main(String[] args) {
            AbstractTemplate template=new ConcreteTemplate();
            template.templateMethod();
        }
    }

    三、应用场景

    目前工作中,对业务功能的实现主要依赖于模板模式的定义,将所有业务分为几种模板进行定义:

    1、查询模板

    2、界面初始化模板

    3、空模板

    4、两步模板

    其中两步模板最为复杂,依次举例说明

    两步模板-工作中常用的模板之一,主要用于需要修改数据的交易,假设通常内部操作为如下步骤
    1、检查数据正确性
    2、记录交易日志,将状态修改为进行中
    3、进行交易操作
    4、根据交易结果,修改交易日志

    那么对于一个功能来讲,记录日志和修改交易结果为相对固定的操作,因此封装在模板里,检查交易正确性和进行交易每个交易均不同,所以需要由具体功能进行实现

    四、应用代码

    package template.example;
    /**
     * @author zjl
     * @time 2016-1-28
     *
     */
    public abstract class TwoPhaseTrsTemplate {
        public void execute() {
            prepare();
            preAction();
            submit();
            afterAction();
        }
        public abstract void prepare();
        public abstract void submit();
        private void preAction(){
            System.out.println("交易开始,交易状态为进行中,记录交易日志");
        }
        private void afterAction(){
            System.out.println("交易成功,更新交易日志状态为成功");
        }
    }

    具体交易,以转账为例:

    package template.example;
    
    public class Transfer extends TwoPhaseTrsTemplate {
    
        @Override
        public void prepare() {
            System.out.println("检查所有转账元素");
        }
    
        @Override
        public void submit() {
            System.out.println("转账操作,银行核心进行扣帐操作");
    
        }
    
    }

    客户端调用

    package template.example;
    
    public class Client {
        public static void main(String[] args) {
            Transfer transfer=new Transfer();
            transfer.execute();
        }
    }

    执行结果:

    检查所有转账元素
    交易开始,交易状态为进行中,记录交易日志
    转账操作,银行核心进行扣帐操作
    交易成功,更新交易日志状态为成功
  • 相关阅读:
    求一个数的阶乘在 m 进制下末尾 0 的个数
    区间dp
    最长公共子序列变形
    学习stm32专区
    C/C++中static关键字详解
    ASP.NET调用Office Com组件权限设置
    TreeView控件
    SQL笔记(1)索引/触发器
    NPOI 1.2.5 教程
    SQL Povit
  • 原文地址:https://www.cnblogs.com/jyyzzjl/p/5167826.html
Copyright © 2020-2023  润新知