欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)

程序员文章站 2022-03-12 12:33:00
一、概述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.(要求一个系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更容...

一、概述

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、通用类图

设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)

        上面的SubSystem还会有更多,但是我们都不管,我们只需要跟Facade这个类打交道就可以了。也就是说Facade是外界访问子系统内部的一个通道,不管子系统内部是多么杂乱无章,都与我们没有关系,只要有Facade在,我们就可以做到“金玉其外,败絮其中”。我们可以通过下图更清晰的理解外观模式。
设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)

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、类图分析

设计模式之外观模式(附:MyBatis中Configuration的外观模式的使用分析)
        由上面的类图可以看出,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

相关标签: 设计模式