Mybatis之设计模式之迭代器模式


了解,什么是迭代器模式?

迭代器模式(Iterator)提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该
对象的内部表示。

1.为什么需要它?

提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

2.适用性

- 访问一个聚合对象的内容而无需暴露它的内部表示
    - 支持对聚合对象的多种遍历
    - 为遍历不同的聚合结构提供一个统一的接口

3.参与者

如图:

Mybatis之设计模式之迭代器模式

  • Iterator(迭代器):迭代器定义访问和遍历元素的接口
  • ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置
  • Aggregate(聚合):聚合定义创建相应迭代器对象的接口
  • ConcreteAggregate(具体聚合):具体聚合实现创建相应迭代器的接口,该操作返
    回ConcreteIterator的一个适当的实例

4.协作

ConcreteIterator跟踪聚合中的当前对象,并能够计算出待遍历的后继对象

5.效果

  • 它支持以不同的方式遍历一个聚合
  • 迭代器简化了聚合的接口
  • 在同一个聚合上可以有多个遍历

Mybatis 源码分析

1.目录

Mybatis之设计模式之迭代器模式

2.类结构

Mybatis之设计模式之迭代器模式

3.源码

package org.apache.ibatis.reflection.property;

import java.util.Iterator;

/**
 * @author Clinton Begin
 */
/**
 * 属性分解器,属性分解为标记,迭代子模式 如person[0].birthdate.year,将依次取
 * 得person[0], birthdate, year
 * 
 */
public class PropertyTokenizer implements Iterable<PropertyTokenizer>, Iterator<PropertyTokenizer> {
    // 例子: person[0].birthdate.year
    /**
     * 名字
     */
    private String name; // person
    /**
     * 名字和下标
     */
    private String indexedName; // person[0]
    /**
     * 下标
     */
    private String index; // 0
    /**
     * 子节点
     */
    private String children; // birthdate.year
    /**
     * 初始化属性分解器
     * @param fullname 全名
     */
    public PropertyTokenizer(String fullname) {
        // person[0].birthdate.year
        // 对参数进行第一次处理,通过“.”分隔符将propertyName分作两部分
        int delim = fullname.indexOf('.');
        if (delim > -1) {
            name = fullname.substring(0, delim);
            children = fullname.substring(delim + 1);
        } else {
            // 找不到.的话,取全部部分
            name = fullname;
            children = null;
        }
        indexedName = name;
        // 把中括号里的数字给解析出来
        // 对name进行二次处理,去除“[...]”,并将方括号内的内容赋给index属性,如果name属性中包含“[]”的话
        delim = name.indexOf('[');
        if (delim > -1) {
            // 先取index内容再截取name更为方便些,要不然还需要一个临时变量,需要三步才能实现
            // 这里包含了一个前提:传入的参数如果有有[,则必然存在],并且是属性的最后一个字符
            index = name.substring(delim + 1, name.length() - 1);
            name = name.substring(0, delim);
        }
    }

    public String getName() {
        return name;
    }

    public String getIndex() {
        return index;
    }

    public String getIndexedName() {
        return indexedName;
    }

    public String getChildren() {
        return children;
    }

    @Override
    public boolean hasNext() {
        return children != null;
    }

    // 取得下一个,非常简单,直接再通过儿子来new另外一个实例
    @Override
    public PropertyTokenizer next() {
        return new PropertyTokenizer(children);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
    }

    @Override
    public Iterator<PropertyTokenizer> iterator() {
        return this;
    }
}

这样应该对这个类比较清晰了吧。

讲解

可以看到,这个类传入一个字符串到构造函数,然后提供了iterator方法对解析后的
 子串进行遍历,是一个很常用的方法类。

如图:

Mybatis之设计模式之迭代器模式

可以看到,在mybatis中的很多地方使用到了PropertyTokenizer,这里就举例
mybatis里的这个元对象MetaObject利用这个类可以对mybatis属性进行分解使之得
到任何想要的属性。

说明

关于PropertyTokenizer这个类。其实,在mybatis中,这个类会被频繁使用,
主要用于属性分解。这个类实现了Iterable和Iterator这两个接口,但在使用时经常
被用到的是Iterator接口中的hasNext这个函数。

附加

这个类里最关键的还是他的构造器public PropertyTokenizer(String 
 fullname),这个里面在初始化的时候就将传进来了fullname进行处理,我们可以
 把它理解成一个属性解析器。

mybatis源码 ------https://gitee.com/SmileSnake/...

参考资料:

迭代器模式
如果有侵权,马上删除

相关推荐