• 【设计模式】模板方法模式


    解释:

      模板方法模式也是也是比较容易理解的,就比如说做饭,同样的步骤不同的人做味道是不一样的。或者是造汽车,同样的步骤,造车厂商不一样,造出来的汽车质量不同。这就是模板方法模式.

    定义:

      它定义一个操作中的算法的框架,而将一些步骤延迟到了子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些步骤。

    核心:

      处理的步骤父类中早已定义好,具体的实现延迟到子类中去完成。

    模板方法的角色:

      1.抽象模板角色:它一般是一个抽象类或者接口,它抽象出操作算法骨架。

      2.具体抽象模板角色:它实现了抽象模板角色的方法,它是操作算法骨架业务的具体化。

    模板方法的优点:

      1.封装不变部分,扩展可变部分。

      2.提取了公共代码,便于维护。

      3.行为由父类控制,子类实现。

    模板方法的缺点:

      1.每一个不同的实现都需要一个子类来实现,这样导致类的个数增加。

    模板模式的使用场景:

      1.实现一个算法时,基本步骤很固定,但是某些部分易变,易变的部分可以抽离出来,由子类实现。

    具体使用描述:

    1. 使用抽象类定义模板类,并在其中定义所有的基本方法、模板方法,钩子方法,不限数量,以实现功能逻辑为主。其中基本方法使用final修饰,其中要调用基本方法和钩子方法,基本方法和钩子方法可以使用protected修饰,表明可被子类修改。

    1. 定义实现抽象类的子类,重写其中的模板方法,甚至钩子方法,完善具体的逻辑。

    代码实现

    public abstract class DBTemplate {
        protected abstract void open();
        protected abstract void select();
        protected abstract void close();
        //一个搜索模板
        public final void selectTemplate(){
            open();
            select();
            close();
        }
    }
    
    public class MysqlDB extends DBTemplate {
        @Override
        protected void open() {
            System.out.println("开启mysql");
        }
        @Override
        protected void select() {
            System.out.println("输入mysql查询语句");
        }
        @Override
        protected void close() {
            System.out.println("关闭mysql");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            DBTemplate mysql = new MysqlDB();
            mysql.selectTemplate();
        }
    }
    
    //开启mysql
    //输入mysql查询语句
    //关闭mysql

    可以加上钩子函数

    public abstract class DBTemplate {
        protected DBTemplate(String name){
            this.name = name;
        }
        protected String name;
        protected abstract void open();
        protected abstract void select();
        protected abstract void close();
        protected abstract void update();
    
        //可以定义一个钩子函数
        protected boolean hookMethod(){
            return true;
        };
        //一个搜索模板
        public final void selectTemplate(){
            open();
            select();
            close();
            if(hookMethod()){
                update();
            }
        }
    }
    
    public class MysqlDB extends DBTemplate {
        public boolean isUse;
        protected MysqlDB(String name) {
            super(name);
        }
        protected MysqlDB(String name,boolean isUse) {
            this(name);
            this.isUse = isUse;
        }
        @Override
        protected void open() {
            System.out.println("开启mysql");
        }
        @Override
        protected void select() {
            System.out.println("输入mysql查询语句");
        }
        @Override
        protected void close() {
            System.out.println("关闭mysql");
        }
        @Override
        protected void update() {
            System.out.println("更新mysql");
        }
        @Override
        protected boolean hookMethod() {
            return isUse;
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            //传true 就会调用update方法
            DBTemplate mysql = new MysqlDB("测试",false);
            mysql.selectTemplate();
        }
    }
    
    //开启mysql
    //输入mysql查询语句
    //关闭mysql

    其他应用 

      JDK 中也有模板方法的身影,比如:AbstractQueuedSynchronizer、多线程 AQS 的实现。Dubbo 中也有模板方法的使用,比如:Dubbo 中负载均衡算法的实现。SpringBatch 中也有,如果你用过这个框架的话!tomcat 的 LifecycleBase 也是模板方法模式,Spring 中的 JdbcTemplate。

      平时开发的时候,比如做一个excel导出功能,也可以将其进行分解,之后根据不同公司的要求,去导出不同的excel。

      如打刻项目,使用hutool poi进行excel导出的时候,有三个管理员角色、普通用户角色、打印、刻录六种日志,他们导出的excel列头都有区别。有的excel还要求有标题,此时就可以使用模板方法模式,步骤大概为:

        1.首先获取数据源

        2.根据不同类型的日志定义sheet页的列头并写入数据

        3.压缩excel到zip下并加密

        4.根据结果记录日志

    参考:

    https://www.jb51.net/article/166685.htm

    https://baijiahao.baidu.com/s?id=1639309117007251878&wfr=spider&for=pc

  • 相关阅读:
    Java Web学习笔记3
    Java学习笔记11
    diff 比较两个文件的差异
    Java学习笔记10
    appium——如何导出夜神模拟器下载“微信”app的apk
    python之文件操作模块(os和shutil)
    浅谈HTTP和HTTPS
    LUNIX命令集
    ubuntu软件管理工具的使用——dpkg和apt
    CSS学习—day1
  • 原文地址:https://www.cnblogs.com/flyinghome/p/15206627.html
Copyright © 2020-2023  润新知