六、模板方法模式在源码中的体现
先来看 JDK 中的 Abstractlist , 来看代码:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { abstract public E get(int index); }
我们看到 get()一个抽象方法 , 那么它的逻辑就是交给子类来实现,我们大家所熟知的 Arraylist
就是 Abstractlist 的子类。同理,有 Abstractlist就有 Abstractset 和 AbstractMap , 有兴趣的小伙伴可以去看看这些的源码实现。还有一个每天都在用的 HttpServlet, 有三个方法 service()和 doGet()、
doPost()方法,都是模板方法的抽象实现。
在 MyBatis框架也有—些经典的应用 ,我们来一下 BaseExecutor 类,它是—个基础的 SQL 执行类,
实现了大部分的 SQL 执行逻辑 ,然后把几个方法交给子类定制化完成 , 源码如下:
public abstract class BaseExecutor implements Executor { protected abstract int doUpdate(MappedStatement ms, Object parameter) throws SQLException; protected abstract List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException; protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException; protected abstract <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql) throws SQLException; }
如 doUpdate、 doFlushStatements、 doQuery、 doQueryCursor 这几个方法就是交由子类来实
现, 那么 BaseExecutor 有哪些子类呢?我们来看一下它的类图:
我们一起来看—下 SimpleExecutor 的 doUpdate 实现
public class SimpleExecutor extends BaseExecutor { @Override public int doUpdate(MappedStatement ms, Object parameter) throws SQLException { Statement stmt = null; try { Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null); stmt = prepareStatement(handler, ms.getStatementLog()); return handler.update(stmt); } finally { closeStatement(stmt); } } }
七、模板模式的优缺点
优点:
1、 利用模板方法将相同处理逻编的代码放到抽象父类中 , 可以提高代码的复用性。
2、 将不同的代码不同的子类中 , 通过对子类的扩展墙加新的行为 , 提高代码的扩展性。
3、 把不变的行为写在父类上 , 去除子类的重复代码 , 提供了一个很好的代码复用平台 , 符合开闭原则。
缺点:
1、 类数目的培加 , 每一个抽象类都需要一个子类来实现 , 这样导致类的个数谧加。
2、 类数呈的培加 , 间接地墙加了系统实现的复杂度。
3、 继承关系自身缺点 , 如果父类添加新的抽象方法 , 所有子类都要改—遍。
文章参考地址:
九、委派模式与模板模式详解