模板方法模式初探

简介: 模板方法模式初探

什么是模板方法模式?

为了介绍什么是模板方法模式,我们再次请出我们的实习生小陈, 为了不涉及公司的核心业务,我们这里在讲述这个故事的时候,要屏蔽一下核心业务牵扯到具体的场景, 这一天领导给小陈安排了一个这样的需求, 用代码模拟制作羊肉汤, 目前已知在制作羊肉的时候都会先清洗,但是烧制方法是不同的,根据经验来说,未来会有更多的羊肉汤来进入到我们的代码中。

小陈收到了这个需求,心里想既然清洗的逻辑是共同的的,那这个简单,我就把清洗抽出来为一个方法,然后再service里面写各自的初加工和烧制方法就可以了。于是写出的代码如下图所示:

/**
 * 这是清洗方法,所有羊肉都要 清洗
 */
public interface MuttonBaseMakeService {
    void waterMutton();
}
/**
 * 再来一个实现类
 */
@Service
public class MuttonBaseMakeServiceImpl implements MuttonBaseMakeService{ 
    @Override
    public void waterMutton() {
        System.out.println("先清洗羊肉");
    }
}
/**
 * 再来一个牛肉汤service
 */
public interface MuttonSoupService{
    /**
  * 单县羊肉汤
 */
    void danXianMuttonSoup();
    /**
    * 河南羊肉汤
 */
    void heNanMuttonSoup();
}
@Service
public class MuttonSoupServiceImpl implements MuttonSoupService{
    @Autowired
    private MuttonBaseMakeService muttonBaseMakeService;
    @Override
    public void danXianMuttonSoup() {
        muttonBaseMakeService.waterMutton();
        System.out.println("单县牛肉汤");
    }
    @Override
    public void heNanMuttonSoup() {
        muttonBaseMakeService.waterMutton();
        System.out.println("河南牛肉汤");
    }
}

感觉完成了任务, 测试也没问题之后,于是找到了领导,领导笑了笑,小陈想了想,上次指导我HttpClient怎么用的时候似乎也是这个笑容(参见HTTP Client 学习笔记 (一) 初遇篇),心里想这估计是代码写的不行。

领导清了清嗓子,然后说道: 我这次分配给你的时候是讲过未来会接入很多的羊肉的做法的,你目前的写法是每接入一种羊肉的做法都是在接口中写,然后在对应的方法写实现对吗?小陈点了点头,说道:是的。

领导接着问道:  每接入一种羊肉汤, 都必须写一遍MuttonBaseMakeService的waterMutton方法,这是第一点。第二点还记得大学的软件工程吗?软件工程相对于其他工程的一个特点就是变化, 其实这个需求我保留了一部分,就是其实羊肉汤制作之后,打包动作是相同的,那找你的思路是不是,每个羊肉汤方法都要加一个打包方法啊,我们公司目前准备接入二十种羊肉汤,那这改动量可不小,有没有其他方法优化一下呢?

小陈想了想,说道:是设计模式吗?

领导点了点头: 要不咱下去搜一下。

经过一番搜索小陈找到了模板方法模式,觉得很适应这个需求,模板方法模式的核心是:父类定义方法的逻辑骨架,而其中一些逻辑步骤的实现放到具体的子类中实现,这样可以做到不改变逻辑结构的前提下定义某些细节的实现。于是将代码改成了如下实现:

/**
 * 父类定义逻辑骨架
 */
public abstract class MuttonSoupBase {
   protected void water(){
       System.out.println("清洗羊肉统一打包");
   }
   public void make(){
       water();
       muttonSoup();
       pack();
   }
    /**
     * 羊肉汤具体制作细节交给子类去实现
     */
   protected abstract void muttonSoup();
   protected void pack(){
       System.out.println("-----打包-----");
   }
}
@Service
public class DanXianMuttonSoup extends MuttonSoupBase{
    @Override
    protected void muttonSoup() {
        System.out.println("-----单县羊肉汤------");
    }
}
@Service
public class HeNanMuttonSoup extends MuttonSoupBase{
    @Override
    protected void muttonSoup() {
        System.out.println("---- 河南羊肉汤-------");
    }
}
/**
 * 简单使用示例
 */
@Service
public class SoupDemo {
    @Autowired
    private List<MuttonSoupBase> muttonSoupBases;
    public void make() {
        for (MuttonSoupBase muttonSoupBase : muttonSoupBases) {
            muttonSoupBase.make();
        }
    }
}

小陈觉得代码没问题了, 就去找到领导。领导点了点头,说道:可以,我们公司持久层用的是MyBatis,在MyBatis中用到了不少设计模式 其中就有模板方法模式,下面我带着你看一下,我们看一下MyBatis中是如何运用模板方法模式的。

MyBatis中的模板方法模式的运用

首先我们MyBatis的基础架构是这样的:

image.png

注意核心层的SQL执行,在MyBatis里面你这是一个接口,我们姑且称之为SQL执行器,定义了基本的SQL执行行为。然后BaseExecutor实现了Executor,也就是模板方法模式中的基类,定义逻辑骨架,具体的实现步骤由具体的子类来完成。如下图所示:

image.png

粗略的说BatchExecutor处理批量执行的SQL语句,批量插入、批量更新、批量删除这些,SimpleExecutor是默认的SQL执行器,每次开启或者关闭都会创建一个StatementHandler对线个,ReuseExecutor 是重用SQL执行器,在某个Statement执行过之后,会将这个Statement缓存到一个Map中。领导还打算往下讲,突然想到小陈只是一个实习生,笑了笑说道:你注意看BaseExecutor 和 BatchExecutor、SimpleExecutor、ReuseExecutor用的就是我们上面讨论的模板方法模式,具体的查询、更新都交给对应的子类来执行,你慢慢体会一下,其实MyBatis里面模板方式用的还不少,再举一个例子StatementHandler,StatementHandler负责MyBatis和JDBC之间的交互,上面三个不同的执行器也对应三个不同的StatementHandler, MyBatis还是选择定义了一个基类BaseStatementHandler,三个子类PreparedStatementHandler、CallableStatementHandler、SimpleStatementHandler处理对应的SQL。这是很经典的实现了,小陈你可以注意体会一下。

相关文章
|
2月前
|
设计模式 算法 Java
Java设计模式-模板方法模式(14)
Java设计模式-模板方法模式(14)
|
3月前
|
设计模式 算法
什么是模板方法模式?
【8月更文挑战第22天】
39 0
|
3月前
|
设计模式 算法
模板方法模式
【8月更文挑战第22天】
28 0
|
6月前
|
设计模式 算法 Java
Java设计模式——模板方法模式
Java设计模式——模板方法模式
|
算法 前端开发
关于模板方法模式我所知道的
关于模板方法模式我所知道的
89 0
|
算法 Java 程序员
行为型模式-模板方法模式
行为型模式-模板方法模式
95 0
|
设计模式
我学会了,模板方法模式
模板方法模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
79 0
我学会了,模板方法模式
|
设计模式 缓存 算法
浅析Java设计模式【3.6】——模板方法
Java常用设计模式,模板模式
134 0
浅析Java设计模式【3.6】——模板方法
|
设计模式 算法 Java
Java设计模式 ->模板方法模式
Java设计模式 ->模板方法模式
96 0
|
设计模式 算法 Java
Java设计模式-模板方法模式
Java设计模式-模板方法模式
154 0
Java设计模式-模板方法模式