结合Mybatis源码看设计模式——外观模式

定义

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

适用场景

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

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

  下面我们看看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图画出

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

原文地址:https://www.cnblogs.com/Cubemen/p/10654121.html

时间: 2024-07-29 17:36:55

结合Mybatis源码看设计模式——外观模式的相关文章

结合JDK源码看设计模式——模板方法模式

前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模板方法模式,你会发现,它与这个问题的答案实际上有很多共同之处. 一.定义 定义一个算法骨架,允许子类为一个或多个步骤提供实现.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤. 二.适用场景 一次性实现一个算法的不变的部分,将可变的行为留给子类实现 也就是将各子类中公共行为被提取

【转】Mybatis源码解读-设计模式总结

原文:http://www.crazyant.net/2022.html?jqbmtw=b90da1&gsjulo=kpzaa1 虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybatis至少遇到了以下的设计模式的使用: Builder模式,例如SqlSessionFactoryBuilder.XMLConfigBuilder.XMLMapperBuilder

结合JDK源码看设计模式——适配器模式

定义: 将一个类的接口转换成客户期望的另外一个接口(重点理解适配的这两个字),使得接口不兼容的类可以一起工作适用场景: 已经存在的类,它的方法和需求不匹配的时候 在软件维护阶段考虑的设计模式 详解 首先来从生活中的常见场景来看,一个电源插座输出都是220V,而我们一些电子设备,比如手机,MP3,MP4,所需要的电压不一样,也不可能直接就是220接上,这就需要一个中间的转换器,每个厂家不同,对应的充电线也有可能不同.这个不同的充电线就可以理解为一个适配器.而220V的输出电压可以看做是我们做好的一

结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂

三种工厂模式的详解: 简单工厂模式: 适用场景:工厂类负责创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑不关心 缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的开闭原则,且产品类多的话,就会使得简单工厂类比较复杂 在jdk源码中的具体实例(注意看代码中的中文注释) private static Calendar createCalendar(TimeZone zone,Locale aLocale) { CalendarProvider provider

结合JDK源码看设计模式——装饰者模式

定义 在不改变原有对象的基础之上,将功能附加到对象上 适用场景 扩展一个类的功能 动态的给对象增加功能,当功能不需要的时候能够动态删除 详解 在看到定义的时候,可能很多人会想,这不就是继承吗?的确很像,不过是比继承更加有弹性的替代方案.就像原型模式和new之间的关系一样,有区别,但是区别又不是特别大.装饰者一个很重要的词就是动态,他可以灵活的选择要这个功能还是不要.在装饰者中要有四个角色:抽象的实体类,具体的实体类,抽象的装饰者,具体的装饰者.下面画一个大致的UML图 实体类创建之后,如果想扩展

结合JDK源码看设计模式——观察者模式

前言: 现在我们生活中已经离不开微信,QQ等交流软件,这对于我们来说不仅是交流,更有在朋友圈中或空间中进行分享自己的生活,同时也可以通过这个渠道知道别人的生活.我们在看朋友圈的时候其实我们扮演的就是一个观察者,朋友圈或空间里的动态可以看作是主体对象.接下来我们就介绍一下观察者模式 一.定义 定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主体对象,当主体对象发生变化时,它的所有观察者都会收到通知并更新. 二.适用场景 1.关联行为场景,建立一套触发机制 这里稍微理解一下,你有一个特别关

Mybatis源码解读-9种设计模式总结

虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式.Mybatis至少遇到了以下的设计模式的使用: Builder模式,例如SqlSessionFactoryBuilder.XMLConfigBuilder.XMLMapperBuilder.XMLStatementBuilder.CacheBuilder:工厂模式,例如SqlSessionFactory.ObjectF

Mybatis源码分析之Cache二级缓存原理 (五)

一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(ServiceProvider Interface) ,所有的MyBatis内部的Cache缓存,都应该实现这一接口 Cache的实现类中,Cache有不同的功能,每个功能独立,互不影响,则对于不同的Cache功能,这里使用了装饰者模式实现. 看下cache的实现类,如下图: 1.FIFOCache:先进

【MyBatis源码分析】select源码分析及小结

示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是select. 本文研究一下select的实现流程,示例代码为: 1 public void testSelectOne() { 2 System.out.println(mailDao.selectMailById(8)); 3 } selectMailById方法的实现为: 1 public M