`
lijingyao8206
  • 浏览: 216949 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

iBATIS&Spring合奏(四)--设计模式in iBATIS

阅读更多
     现在总结一下iBATIS框架中用到的优美的设计模式。并不是强调设计模式有多强大或者iBATIS有多牛叉,只是在看源码的过程中的一些丝丝缕缕,觉得有很多值得学习的地方。按照不同层次的实现一点点分析和整理。以下的类图和序列图有画的不到位的地方请见谅,因为实在不很在行,用EA画图很痛苦……
      一、SQL Map配置解析
      关于配置文件的解析,iBATIS运用了DOM解析加动态代理的方式实现。其中运用了大量经典的设计模式。为了简单说明源码中应用设计模式的核心API。将于下文以看图说话的方式展现关于设计模式在iBATIS框架中的应用探讨。
       1、基于策略模式(Strategy)解析SqlMapConfig——Nodelete,一个XML节点接口。
       先简单说明下策略模式(Strategy)。Gof提供的解释是针对一组算法,进行封装到有共同接口的独立类中,这样就可以像选择不同的策略一样替换算法。按照字面还是很好理解的。下面画张图(万恶的图啊……EA画图的原文件也会共享给大家,需要EA软件)


     显然,Nodelete接口就是传说中的Strategy,Nodelete是Context角色。SqlMapConfigParser类中创建的匿名类是ConcreteStrategy角色。SqlMapConfigParser在实例化构造函数中调用具体的addXX方法,这些方法内部匿名类实现了process方法。根据XML配置文件不同的节点,采用不同的处理节点方式,而具体的实现就在这些方法中的内部类对象。而解析是遍历节点方式,主要实现是在NodeleteParser中。大家可以参看该类中的源码,运用了DOM方式解析。通过策略模式使不同节点处理方式灵活调用,相互替换。
      2、基于调停者模式(Mediator)实现的对象解析——XmlParserState。
      Mediator也叫协调者,中介者。一个比较通俗的解释是:Mediator设计有与组件沟通的介面,介面中封装了与其它组件互动细节,组件与组件之间不用知道彼此的存在,它们只要与Mediator沟通就好了,利用这种方式,可以切开组件与组件之间的耦合。那在iBATIS框架解析节点时,这个中间者就是要达到一个通用的效果,因为节点之间有包含关系,但是解析方式是不同的。而作为协调方——XmlParserState出现了。先看看图图:



     做些解释。SqlMapConfigParser实例化对象是主解析类。先看一下人家的构造函数吧:

public class SqlMapConfigParser {

  protected final NodeletParser parser = new NodeletParser();
  private XmlParserState state = new XmlParserState();

  private boolean usingStreams = false;

  public SqlMapConfigParser() {
    parser.setValidation(true);
    parser.setEntityResolver(new SqlMapClasspathEntityResolver());

    addSqlMapConfigNodelets();
    addGlobalPropNodelets();
    addSettingsNodelets();
    addTypeAliasNodelets();
    addTypeHandlerNodelets();
    addTransactionManagerNodelets();
    addSqlMapNodelets();
    addResultObjectFactoryNodelets();

  }

      当然后面呢,就通过XmlParserState对象转移数据给SqlMapConfiguration实例化对象。当然SqlMapConfiguration又涉及到门面模式,后面再说。SqlMapConfiguration对象最后传递到两个实例化对象——SqlMapExecutorDelegate和SqlMapClientImpl对象。当配置文件的节点是settings、typeAlias等时,SqlMapConfigParser 就会把XmlParserState作为中介者把节点信息传递给SqlMapConfiguration对象。简单看一下SqlMapConfigParser 处理一个节点的源码:
private void addTypeAliasNodelets() {
    parser.addNodelet("/sqlMapConfig/typeAlias", new Nodelet() {
      public void process(Node node) throws Exception {
        Properties prop = NodeletUtils.parseAttributes(node, state.getGlobalProps());
        String alias = prop.getProperty("alias");
        String type = prop.getProperty("type");
        state.getConfig().getTypeHandlerFactory().putTypeAlias(alias, type);
      }
    });
  }

     上面的最后一行就是将节点信息传递给state-XmlParserState对象的证据。可见把这些节点的处理通过中介者的协调传递给具体的解析实现类使得架构达到解耦的目的。
      还提到了一个门面模式,这里简单说一下,不画图了。门面模式有一个顶级接口,一般是为了提供给子系统一个一致的行为或界面所设。Facade模式隐藏了各个元件之间的合作行为,以及元件本身的操作与设定细节,也失去了一些直接操作元件的方便性。在SqlmapConfiguration作为Sql Map配置Facade的同时,对于其封装的下面的ParemeterMapConfig,ResultMapConfig,CacheModelConfig以及MappedStatementConfig等对于上述XmlParserState提供了方便。而上面提到的以及应用Facade--SqlMapExecutorDelegate就做了具体的提供调配运行的工作。也是看看它的构造函数:
public SqlMapExecutorDelegate() {
    mappedStatements = new HashMap();
    cacheModels = new HashMap();
    resultMaps = new HashMap();
    parameterMaps = new HashMap();

    sqlExecutor = new SqlExecutor();
    typeHandlerFactory = new TypeHandlerFactory();
    dataExchangeFactory = new DataExchangeFactory(typeHandlerFactory);
  }
 
    此类后面就通过MappedStatement执行了相应的持久化操作。
    关于配置解析方面的API就先介绍到这里。当然只是一小部分的一小部分了。后面会有事务处理,SqlMap引擎实现,以及一些缓存实现运用到的设计模式加以介绍。这是个艰苦的过程,因为画图是个艰苦的过程……
    后面会继续加进来内容。现在是冷笑话时间:
    比尔盖茨的新家落成后,发现设计师跟他开了玩笑:1)按门铃后,大门两分钟才能启动,2)不能兼容旧家的灯泡,需要买新灯泡,3)电灯开关要双点击,4)一次只能打开一扇窗子,5)每晚睡前需要选择“休眠”、“睡眠”、“待机”,6)冲马桶时,马桶会问你:“你确定你要冲马桶吗?”
  • 大小: 77.3 KB
  • 大小: 55.4 KB
2
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics