设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)
一、概述
1、定义
Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher-level interface that makes the subsystem easier to use.(要求一个系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更容易使用)。
2、通用类图
上面的SubSystem还会有更多,但是我们都不管,我们只需要跟Facade这个类打交道就可以了。也就是说Facade是外界访问子系统内部的一个通道,不管子系统内部是多么杂乱无章,都与我们没有关系,只要有Facade在,我们就可以做到“金玉其外,败絮其中”。我们可以通过下图更清晰的理解外观模式。
3、基本介绍
外观模式有两个角色,一个是门面角色(或者是外观角色,外观模式也叫做门面模式),另一个是就是子系统角色。
- Facade门面角色:门面角色没有实际的业务逻辑,它知道子系统的所有功能和责任,其作用就是将Client发出的请求委派到相应的子系统中去。
- subsystem子系统角色:可以有有一个或者是多个子系统,每一个子系统都是一个类的集合。
二、通用源码
subsystem角色:
//子系统A
public class SubSystemA {
public void methodA(){
//业务逻辑A
}
}
//子系统B
public class SubSystemB {
public void methodB(){
//业务逻辑B
}
}
Facade角色:
public class Facade {
//被委托的对象
private SubSystemA subSystemA=new SubSystemA();
private SubSystemB subSystemB=new SubSystemB();
//提供给外部访问的方法
public void method(){
subSystemA.methodA();
}
public void methodB(){
subSystemB.methodB();
}
}
三、外观模式的应用
1、优点
- 减少客户端对子系统的依赖:Client所要做的事情直接找Facade就可以了,而不是直接去依赖子系统;
- 提高了安全性:可以通过门面类对client所要访问的方法进行控制。
2、缺点
- 不符合开闭原则:在不对外观类进行抽象的时候,如果需要添加新的子系统,就需要对Facade类进行修改。
3、门面模式的使用场景
- 为一个复杂的模块或子系统提供一个外界访问的接口;
- 子系统相对独立——外界对子系统的访问只要黑箱操作即可(不知道黑箱操作是啥,特意百度了一下。-_ - ! -_-! 黑箱操作:办理业务或处理事情时,不是公开进行,而是背地里或私下进行,甚至是偷偷进行。);
四、Configuration源码结构分析
1、类图分析
由上面的类图可以看出,client只需要调用Configuration的newMetaObject(Object object)
方法就可以得到一个MetaObject对象,而具体的对象是怎么生成与client无关,下面我们可以看一下Configuration的部分源码分析。
2、Configuration部分源码
//Configuration 类:
public class Configuration {
protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
protected ObjectFactory objectFactory = new DefaultObjectFactory();
protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
public MetaObject newMetaObject(Object object) {
return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}
//MetaObject类
public class MetaObject {
private Object originalObject;
private ObjectWrapper objectWrapper;
private ObjectFactory objectFactory;
private ObjectWrapperFactory objectWrapperFactory;
private ReflectorFactory reflectorFactory;
public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
if (object == null) {
return SystemMetaObject.NULL_META_OBJECT;
} else {
return 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);
}
}
}
由上面的部分源码可以看出,客户端只需要调用Configuration的newMetaObject(Object object)
方法,并传递一个Object参数,就可以获取对应的MetaObject,至于具体的产生什么样的MetaObject,则有MetaObject的类的forObject(object, objectFactory, objectWrapperFactory, reflectorFactory)
方法实现。
本文地址:https://blog.csdn.net/qq_42339210/article/details/107455638
推荐阅读
-
设计模式中的facade外观模式在JavaScript开发中的运用
-
实例解析设计模式中的外观模式在iOS App开发中的运用
-
Mybatis入门案例中设计模式的简单分析
-
设计模式中的facade外观模式在JavaScript开发中的运用
-
设计模式系列之组合模式及其在JDK和MyBatis源码中的运用详解
-
设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)
-
Ruby设计模式编程中对外观模式的应用实例分析
-
Mybatis入门案例中设计模式的简单分析
-
分析Python中设计模式之Decorator装饰器模式的要点
-
设计模式之命令模式(附:JdbcTemplate中命令模式的应用分析)