结合Mybatis源码看设计模式——外观模式
定义
提供了一个统一的接口,用来访问子系统中一群接口
适用场景
- 子系统复杂,增加外观模式提供简单调用接口
- 构建多层系统结构,用外观对象作为每层入口
详解
外观模式,主要理解外观。通俗一点可以认为这个模式是将子系统封装到一起,提供给应用的层面就提供一个方法。不直接由应用层直接访问子系统。
下面我们看看ibatis的源码来具体理解外观模式。
public metaobject newmetaobject(object object) { return metaobject.forobject(object, this.objectfactory, this.objectwrapperfactory, this.reflectorfactory); }
上述代码其实是完成一个创建metaobject的事情,但是它是将一个负责创建metaobject的子系统放在了这个方法里面。为什么要这么做?实际上如果直接让我们应用层去使用metaobject.forobject(object, this.objectfactory, this.objectwrapperfactory, this.reflectorfactory);这个方法。可以看出参数实在太多,而configuration类使用外观模式,外观类并不具体实现什么,他只是负责调用和管理子系统
下面看看configuration中的构造器
可以把上面的objectfactory,objectwrapperfactory,reflectorfactory看作三个子系统
接下来到metaobject的里面看看forobject方法
public static metaobject forobject(object object, objectfactory objectfactory, objectwrapperfactory objectwrapperfactory, reflectorfactory reflectorfactory) { return object == null ? systemmetaobject.null_meta_object : new metaobject(object, objectfactory, objectwrapperfactory, reflectorfactory); }
对应的构造函数
private metaobject(object object, objectfactory objectfactory, objectwrapperfactory objectwrapperfactory, reflectorfactory reflectorfactory) { this.originalobject = object; this.objectfactory = objectfactory; this.objectwrapperfactory = objectwrapperfactory; this.reflectorfactory = reflectorfactory; if (object instanceof objectwrapper) { this.objectwrapper = (objectwrapper)object; } else if (objectwrapperfactory.haswrapperfor(object)) { this.objectwrapper = objectwrapperfactory.getwrapperfor(this, object); } else if (object instanceof map) { this.objectwrapper = new mapwrapper(this, (map)object); } else if (object instanceof collection) { this.objectwrapper = new collectionwrapper(this, (collection)object); } else { this.objectwrapper = new beanwrapper(this, object); } }
可以看出这个metaobject也是个将构造器私有的特殊单例模式,大致分析了一下就用下面的uml图画出
总结:
外观模式和前面讲的模式不是太一样,外观模式只是一个结构而已,前面几篇博客更多的是创建型的设计模式。就是使用这个设计模式可以具体完成类的创建,实例化等等,而外观模式更多考虑是客户端使用的方便,是在子系统和客户端之间的一个帮手。在生活中就像房屋中介一样,如果你想买二手房,你自己可能找不到很好的房源,但是你找中介只需要告诉他们房子大概多大,在哪,几层,中介就会帮你找到这样的房子并提供给你。当然了,设计模式还是要结合具体的业务来说,不能说学了外观模式,就完全禁止客户端和子系统的交互。
推荐阅读
-
Mybaits 源码解析 (十一)----- 设计模式精妙使用:静态代理和动态代理结合使用:@MapperScan将Mapper接口生成代理注入到Spring
-
结合JDK源码看设计模式——单例模式(未完待续)
-
结合JDK源码看设计模式——建造者模式
-
结合Mybatis源码看设计模式——外观模式
-
结合JDK源码看设计模式——模板方法模式
-
荐 BAT高频面试系列:设计模式+Spring源码+MyBatis+SpringMVC多线程+MySQL+Redis+框架使用+数据结构算法答案和总结
-
结合JDK源码看设计模式——适配器模式
-
结合JDK源码看设计模式——迭代器模式
-
结合Mybatis源码说说sqlSession创建流程和从中用到的一些设计模式
-
结合JDK源码看设计模式——原型模式