文章目录
  1. 1. 创建型模式(Creational Patterns)
    1. 1.1. 工厂方法模式(Factory Method pattern)
    2. 1.2. 建造者模式(Builder pattern)
  2. 2. 结构型模式(Structural Patterns)
    1. 2.1. 装饰器模式(Decorator pattern)
    2. 2.2. 动态代理模式(Proxy pattern)

理解设计模式的最好方法就是在实际框架代码中去学习,看别人是怎么实现的,以及在哪种场景中使用这种模式。mybatis源码中也使用了一些设计模式,把目前发现的模式做个记录:

创建型模式(Creational Patterns)

工厂方法模式(Factory Method pattern)

一对一的关系,一个工厂创建一个与其对应的对象,由子类实现创建对象的操作:

参考JdbcTransactionFactory和DefaultObjectFactory.create(),DefaultObjectFactory.create()代码实现如下:

@SuppressWarnings("unchecked")
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    Class<?> classToCreate = resolveInterface(type);
    // we know types are assignable
    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
}

建造者模式(Builder pattern)

创建的对象属性比较复杂,要分步骤处理,还是就是构造函数传的参数比较多的情况,对构造函数进行拆分,最后返回一个对象。

具体实现也可以不用抽象的Builder,视具体情况而定,可以参考ResultMap:

public ResultMap build() {
      if (resultMap.id == null) {
        throw new IllegalArgumentException("ResultMaps must have an id");
      }
      resultMap.mappedColumns = new HashSet<String>();
      resultMap.idResultMappings = new ArrayList<ResultMapping>();
      resultMap.constructorResultMappings = new ArrayList<ResultMapping>();
      resultMap.propertyResultMappings = new ArrayList<ResultMapping>();
      for (ResultMapping resultMapping : resultMap.resultMappings) {
          //判断是内嵌查询还是内嵌结果集
        resultMap.hasNestedQueries = resultMap.hasNestedQueries || resultMapping.getNestedQueryId() != null;
        resultMap.hasNestedResultMaps = resultMap.hasNestedResultMaps || (resultMapping.getNestedResultMapId() != null && resultMapping.getResultSet() == null);
        final String column = resultMapping.getColumn();
        if (column != null) {
            //将内部标签属性为column的添加早已映射列
          resultMap.mappedColumns.add(column.toUpperCase(Locale.ENGLISH));
        } else if (resultMapping.isCompositeResult()) {
          for (ResultMapping compositeResultMapping : resultMapping.getComposites()) {
            final String compositeColumn = compositeResultMapping.getColumn();
            if (compositeColumn != null) {
              resultMap.mappedColumns.add(compositeColumn.toUpperCase(Locale.ENGLISH));
            }
          }
        }
        if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
          resultMap.constructorResultMappings.add(resultMapping);
        } else {
          resultMap.propertyResultMappings.add(resultMapping);
        }
        if (resultMapping.getFlags().contains(ResultFlag.ID)) {
          resultMap.idResultMappings.add(resultMapping);
        }
      }
      if (resultMap.idResultMappings.isEmpty()) {
        resultMap.idResultMappings.addAll(resultMap.resultMappings);
      }
      // lock down collections
      resultMap.resultMappings = Collections.unmodifiableList(resultMap.resultMappings);
      resultMap.idResultMappings = Collections.unmodifiableList(resultMap.idResultMappings);
      resultMap.constructorResultMappings = Collections.unmodifiableList(resultMap.constructorResultMappings);
      resultMap.propertyResultMappings = Collections.unmodifiableList(resultMap.propertyResultMappings);
      resultMap.mappedColumns = Collections.unmodifiableSet(resultMap.mappedColumns);
      return resultMap;
    }
}

结构型模式(Structural Patterns)

组织各个独立的对象,形成一个更强大的对象。

装饰器模式(Decorator pattern)

通过传入的委派对象,去改变本身对象的责任与行为:

参考执行器CachingExecutor、以及缓存实现都用了装饰器模式,CachingExecutor就是一个装饰对象代码如下,通过构造函数传入委派对象Executor :

public class CachingExecutor implements Executor {
    private static final Logger log = LoggerFactory.getLogger(CachingExecutor.class);

  private Executor delegate;
  private TransactionalCacheManager tcm = new TransactionalCacheManager();

  public CachingExecutor(Executor delegate) {
    this.delegate = delegate;
    delegate.setExecutorWrapper(this);
  }
......
}

动态代理模式(Proxy pattern)

由JDK的Proxy对象生成代理对象,运行期间动态执行目标方法。

参考MapperProxyFactory(相当于客户端)、MapperProxy(代理对象)、SqlSession(委派执行对象),MapperProxy执行源码:

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {
      try {
        return method.invoke(this, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
    //缓存真实调用方法,args为真实方法的参数
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    log.debug("执行Mapper类中的方法");
    return mapperMethod.execute(sqlSession, args);
}

此外mybatis的logging包下面的ConnectionLogger、PreparedStatementLogger、ResultSetLogger等都是动态代理对象。

参考资料:维基百科Creational patternStructural patternBehavioral pattern

文章目录
  1. 1. 创建型模式(Creational Patterns)
    1. 1.1. 工厂方法模式(Factory Method pattern)
    2. 1.2. 建造者模式(Builder pattern)
  2. 2. 结构型模式(Structural Patterns)
    1. 2.1. 装饰器模式(Decorator pattern)
    2. 2.2. 动态代理模式(Proxy pattern)