跳至主要內容

Template Method

ChenSino原创设计模式大约 2 分钟

定义

模板方法模式(Template Method Pattern)是一种行为型设计模式,定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。这种设计模式是一种控制反转的实现方式。因为高层代码不再确定(控制)算法的处理流程。模板方法模式多用在某些类别的算法中,实现了相同的方法,造成代码的重复。这个设计模式和策略模式很像,不同的是,模板方法会有一些通用的逻辑,而策略模式是整个方法重写。从类的继承结构也可以看出来,模板方法是提供一个抽象类,有一个通用的方法,不通用的逻辑放到子类去实现,而策略模式是子类直接继承自接口,要重写整个方法。

例子

mybatis中org.apache.ibatis.executor.BaseExecutor和他的子类是典型的模板方法模式。

mybatis中类型处理器也是典型的模板方法,具体在org.apache.ibatis.type.BaseTypeHandler#setParameter,如下,看类名就知道和BaseExecutor 一个套路,它实现了setParameter方法,但是仔细看,它调用了setNonNullParameter(ps, i, parameter, jdbcType);,如果用户自定义类类型处理器 最终调用的其实是setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType),这个方法是个抽象的方法,等待 用户实现。也是一个经典的模板方法模式,相同逻辑放在一个方法,不同的部分,调用一个抽象方法,让用户自行实现。


  @Override
  public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
    if (parameter == null) {
      if (jdbcType == null) {
        throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
      }
      try {
        ps.setNull(i, jdbcType.TYPE_CODE);
      } catch (SQLException e) {
        throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
            + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
            + "Cause: " + e, e);
      }
    } else {
      try {
        setNonNullParameter(ps, i, parameter, jdbcType);
      } catch (Exception e) {
        throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . "
            + "Try setting a different JdbcType for this parameter or a different configuration property. " + "Cause: "
            + e, e);
      }
    }
  }



    public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType)
      throws SQLException;