前言
上篇介绍了MyBatis源码中对设计模式的应用,这篇我们继续!(纯属废话,但这是我的一个写作模板,不写点总觉得怪怪的)
迭代器模式
介绍:该模式属于行为型,依赖一个迭代器的接口,顺序访问对象各个元素而不暴露内部细节,也就是对遍历进行封装
迭代器模式典型特征就是实现了Iterator接口,该模式的核心诉求是围绕着遍历来实现的,MyBatis源码中对CursorIterator,PropertyTokenizer的遍历就用到了迭代器模式
private class CursorIterator implements Iterator<T> {/*** Holder for the next object to be returned.*/T object;/*** Index of objects returned using next(), and as such, visible to users.*/int iteratorIndex = -1;/*** 自己来实现是否有下一个数据的依据* @return true or false*/@Overridepublic boolean hasNext() {if (object == null) {object = fetchNextUsingRowBound();}return object != null;}/*** 自己来实现获取下一个数据的依据* @return value*/@Overridepublic T next() {// Fill next with object fetched from hasNext()T next = object;if (next == null) {next = fetchNextUsingRowBound();}if (next != null) {object = null;iteratorIndex++;return next;}throw new NoSuchElementException();}@Overridepublic void remove() {throw new UnsupportedOperationException("Cannot remove element from Cursor");}}
模板模式
介绍:该模式属于行为型,继承复用思想,将具体的实现延迟到子类来实现
**
这种平常见的多,工作中也用的多,一般的使用方式是定义一个接口骨架,让抽象类实现它初始化通用代码,再让具体的子类来完成不同的实现。
/*** 提供一个基本骨架*/public interface Executor {// 省略好多代码...ResultHandler NO_RESULT_HANDLER = null;int update(MappedStatement ms, Object parameter) throws SQLException;}
/*** 初始化一些通用代码*/public abstract class BaseExecutor implements Executor {// 省略好多代码...@Overridepublic int update(MappedStatement ms, Object parameter) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());if (closed) {throw new ExecutorException("Executor was closed.");}clearLocalCache();return doUpdate(ms, parameter);}// 延迟到子类去是实现protected abstract int doUpdate(MappedStatement ms, Object parameter) throws SQLException;// 省略好多代码...}
/*** 具体的子类展开具体的实现*/public class SimpleExecutor extends BaseExecutor {/*** 在子类中实现具体逻辑*/@Overridepublic 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);}}// 省略好多代码...}
组合模式
介绍:该模式属于结构型,将对象组合成树结构来体现整体和部份的关系,能够以一致的方式来处理部份和整体
这个听起来有点绕,摘抄了《Head First设计模式》中的一张图,MyBatis中SqlNode是根节点,它的所有实现类可以算是子节点,由此来实现动态SQL,可以任意加入节点,而不影响整体,可插可拔,非常方便。

/*** 根节点*/public interface SqlNode {boolean apply(DynamicContext context);}/*** 子节点 <choose> 标签*/public class ChooseSqlNode implements SqlNode {// 省略好多代码...@Overridepublic boolean apply(DynamicContext context) {for (SqlNode sqlNode : ifSqlNodes) {if (sqlNode.apply(context)) {return true;}}if (defaultSqlNode != null) {defaultSqlNode.apply(context);return true;}return false;}}/*** 子节点 <if> 标签*/public class IfSqlNode implements SqlNode {// 省略好多代码...@Overridepublic boolean apply(DynamicContext context) {if (evaluator.evaluateBoolean(test, context.getBindings())) {contents.apply(context);return true;}return false;}}
小结
对于设计模式看起来简单,但每一种设计思想光看会了还不行,最好找到其典型应用代码,自己抄一遍或者两遍,才能体会到精妙所在。所以:
一定要动手写写写代码!!!
参考
请你相信我所说的都是错的
