【设计模式】模板方法模式
模板方法模式也是也是比较容易理解的,就比如说做饭,同样的步骤不同的人做味道是不一样的。或者是造汽车,同样的步骤,造车厂商不一样,造出来的汽车质量不同。这就是模板方法模式.
定义:
它定义一个操作中的算法的框架,而将一些步骤延迟到了子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些步骤。
核心:
处理的步骤父类中早已定义好,具体的实现延迟到子类中去完成。
模板方法的角色:
1.抽象模板角色:它一般是一个抽象类或者接口,它抽象出操作算法骨架。
2.具体抽象模板角色:它实现了抽象模板角色的方法,它是操作算法骨架业务的具体化。
模板方法的优点:
1.封装不变部分,扩展可变部分。
2.提取了公共代码,便于维护。
3.行为由父类控制,子类实现。
模板方法的缺点:
1.每一个不同的实现都需要一个子类来实现,这样导致类的个数增加。
模板模式的使用场景:
1.实现一个算法时,基本步骤很固定,但是某些部分易变,易变的部分可以抽离出来,由子类实现。
具体使用描述:
-
使用抽象类定义模板类,并在其中定义所有的基本方法、模板方法,钩子方法,不限数量,以实现功能逻辑为主。其中基本方法使用final修饰,其中要调用基本方法和钩子方法,基本方法和钩子方法可以使用protected修饰,表明可被子类修改。
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