定义

  提供了一个统一的接口,用来访问子系统中一群接口

适用场景

  1. 子系统复杂,增加外观模式提供简单调用接口
  2. 构建多层系统结构,用外观对象作为每层入口

详解
  外观模式,主要理解外观。通俗一点可以认为这个模式是将子系统封装到一起,提供给应用的层面就提供一个方法。不直接由应用层直接访问子系统。
     结合Mybatis源码看设计模式——外观模式-LMLPHP

  下面我们看看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中的构造器
结合Mybatis源码看设计模式——外观模式-LMLPHP

  可以把上面的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图画出
结合Mybatis源码看设计模式——外观模式-LMLPHP


总结:
  外观模式和前面讲的模式不是太一样,外观模式只是一个结构而已,前面几篇博客更多的是创建型的设计模式。就是使用这个设计模式可以具体完成类的创建,实例化等等,而外观模式更多考虑是客户端使用的方便,是在子系统和客户端之间的一个帮手。在生活中就像房屋中介一样,如果你想买二手房,你自己可能找不到很好的房源,但是你找中介只需要告诉他们房子大概多大,在哪,几层,中介就会帮你找到这样的房子并提供给你。当然了,设计模式还是要结合具体的业务来说,不能说学了外观模式,就完全禁止客户端和子系统的交互。

04-04 21:24