MyBatis源码分析之迭代器模式和组合模式的应用

迭代器模式的应用

迭代器模式:又称游标模式,提供一种方法访问容器对象中的各个元素,而又不需要暴露该对象的内部实现细节,分离了集合对象的遍历行为,抽象出一个迭代器类来负责。

迭代器模式的组成:
1. Iterator:迭代器定义访问和遍历元素的接口。
2. ConcreteIterator:具体迭代器实现迭代器接口。对该聚合遍历时跟踪当前位置。
3. Aggregate:聚合定义创建相应迭代器对象的接口。
4. ConcreteAggregate:具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例.

MyBatis的源码包cursor就是迭代器模式的应用,下面是缓存包的包结构:
MyBatis源码分析之迭代器模式和组合模式的应用_第1张图片

从上面的包结构图结合具体的代码可知内容如下:

1.java.util.Iterator接口就是定义访问和遍历元素的接口

public interface Iterator {}

2.DefaultCursor的私有内部实现类CursorIterator实现了Iterator

private class CursorIterator implements Iterator<T> {}

3.Cursor接口就是聚合定义创建相应迭代器对象的接口:Aggregate

public interface Cursor<T> extends Closeable, Iterable<T> {}

4.DefaultCursor就是具体实现创建相应迭代器的接口:ConcreteAggregate

public class DefaultCursor<T> implements Cursor<T> {
    // 持有迭代器接口的对象
    private final CursorIterator cursorIterator = new CursorIterator();
    // 返回适当的迭代器接口的对象
    @Override
    public Iterator iterator() {
            if (iteratorRetrieved) {
                throw new IllegalStateException("Cannot open more than one iterator on a Cursor");
            }
            iteratorRetrieved = true;
            return cursorIterator;
    }
}

组合模式的应用

组合模式:层级和树形结构来表示整体和部分的关系,模糊了简单和复杂元素的概念,从而使客户端可以使用同一的方式来处理部分对象和整体对象。

组合模式的组成:
1. Component:为组合中的对象声明接口。在适当的情况下,实现所有类共有接口的缺省行为。声明一个接口用于访问和管理Component的子组件。 (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
2. Leaf:在组合中表示叶节点对象,叶节点没有子节点。在组合中定义节点对象的行为。
3. Composite:定义有子部件的那些部件的行为。存储子部件。在Component接口中实现与子部件有关的操作。
4. Client:通过Component接口操纵组合部件的对象。

MyBatis需要解析的配置文件和映射文件均为XML文件,结构为树形的结构,描述XML文件的数据结构XNode或SqlNode都是组合模式的应用。

以SqlNode为例,下方是SqlNode的继承关系图:
MyBatis源码分析之迭代器模式和组合模式的应用_第2张图片

上方的SqlNode的关系图就是为了存储和解析映射文件中的sql节点的,我们看一下映射文件的sql节点的简单结构:

<sql id="">
    <choose>choose>
    <foreach collection="">foreach>
    <if test="">if>
    <trim>
        <set>set>
        <where>where>
    trim>
sql>

XMLScriptBuilder,类似于Client,用于操作SqlNode节点。类图如下:
MyBatis源码分析之迭代器模式和组合模式的应用_第3张图片

此类中定义了一系列的私有Handler,用于将XNode节点转化为持有SqlNode的List对象

private interface NodeHandler {
    void handleNode(XNode nodeToHandle, List targetContents);
}

你可能感兴趣的:(MyBatis,设计模式)