从2018年开始,我的简历上就有一句话很屌:学完Mybatis的源码,每次面试都会被问到Mybatis中的设计模式。面试官问:既然你研究过Mybatis的源码,那你从哪里说起Mybatis常用的设计模式呢?我基本上先回答相关的设计模式。我:单量模式、代理模式、工厂模式、装饰者模式……说一堆设计模式吧。面试官:能不能说说装饰器模式在Mybatis中是用在什么场景下的?我一般先说什么是装饰器模式,有什么好处,在Mybatis中用在什么地方,这样用有什么好处。接下来,面试官通常会抓住其中的两三个。也是为了不让退伍军人被问到更多问题,今天整理一下。BuilderDesignPattern建造者模式(BuilderPattern)使用多个简单的对象逐步构建一个复杂的对象。这种类型的设计模式是一种创建模式,它提供了一种创建对象的最佳方式。Mybatis中有SqlSessionFactoryBuilder,它构建SqlSessionFactory,它使用的是builder模式。另外,在Mybatis中,以Builder结尾的类名基本上就是一种建造者模式。下面是Mybatis中一个非常完整的构建器模式:XMLConfigBuilder:XML配置构建器,构建器模式,继承自BaseBuilder。工厂模式是专门创建某个对象的工厂。你要什么东西,尽管说,能造出来我就造出来。您不需要知道它是如何创建的。Mybatis中以Factory结尾的类基本上都是使用工厂模式。生活中的案例:很多外包公司做银行系统。银行只要给他需求,给我建个系统就行了。外包公司拼命要求退伍军人加班,最后把他们赶了出去。外包公司是工厂,银行是客户。不管你怎么把客户弄出来,外包公司是不会告诉银行的。例如:SqlSessionFactory:创建一个SqlSession对象。ObjectFactory:对象工厂,所有对象都必须由工厂生产。MapperProxyFactory:创建映射器代理MapperProxy对象。单例模式单例模式是Java中最简单的设计模式之一。这种类型的设计模式是一种创建模式,它提供了一种创建对象的最佳方式。此模式涉及一个类,该类负责创建自己的对象,同时确保只创建一个对象。此类提供了一种直接访问其唯一对象的方法,而无需实例化此类的对象。生活案例:习近平只能有一个,太阳只能有一个,月亮只能有一个。org.apache.ibatis.logging.LogFactory,日志工厂类。为什么是单例模式?如下代码:org.apache.ibatis.executor.ErrorContext,代理模式在代理模式(ProxyPattern)中,一个类代表另一个类的功能。这种类型的设计模式是一种结构模式。生活中的案例:房产中介、婚恋中介、黄牛等都是中介模式。Mybatis实现的核心,比如MapperProxy创建一个代理类用于绑定我们开发的Mapper和Mapper.xml,Plugin为每个插件创建一个代理类。在Mybatis中,尤其是动态代理使用得相当多。建议先学习代理模式,再学习动态代理(JDK和CGlib)。想要看Mybatis的源码,必须掌握动态代理。适配器模式适配器模式(AdapterPattern)用作两个不兼容接口之间的桥梁。这种类型的设计模式是一种结构模式,结合了两个独立界面的功能。此模式涉及负责加入独立或不兼容的接口功能的单个类。在Mybatis、Log中,对于Log4j、JDK、longing等没有直接与slf4j接口的日志组件,需要适配器。模板方法模式在模板模式(TemplatePattern)中,一个抽象类公开定义了执行其方法的方式/模板。它的子类可以根据需要覆盖方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式是一种行为模式。定义操作中算法的框架,将一些步骤推迟到子类。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。以Mybatis为例,父类BaseExecutor,子类SimpleExecutor、BatchExecutor、ReuseExecutor。还有BaseTypeHandler和IntegerTypeHandler等所有子类;基本上就是在父类中实现一个公共方法,然后创建一个抽象方法,交给子类去实现。这种抽象方法也称为钩子方法。装饰模式装饰模式允许在不改变现有对象结构的情况下向现有对象添加新功能。这种类型的设计模式是一种结构模式,它充当现有类的包装器。此模式创建一个装饰类来包装原始类并提供附加功能,同时保持类方法签名的完整性。在实际开发中,大多用于扩展老项目的一些功能。这种模式一般不会在新项目中使用。生活案例:人靠衣服,马靠鞍。美颜相机,没有相机,美图秀秀。这种设计模式侧重于扩展现有功能。在Mybatis中,Cache的实现类LruCache、FifoCache等都装饰了一个类PerpetualCache。常见的代码格式是在被装饰类中会有一个被装饰类的属性,这个属性也是构造函数的一个参数。责任链模式责任链模式为请求创建一个接收者对象链。在给定请求类型的情况下,此模式将请求的发送方和接收方解耦。这种类型的设计模式是一种行为模式。在这种模式中,通常每个接收器都包含对另一个接收器的引用。如果对象无法处理该请求,它会将同一请求传递给下一个接收者,依此类推。生活案例:我们在OA系统发起一个审批,显示项目经理,然后是部门经理,然后是HR,最后是老板。面试流程为组长面试、项目经理面试、部门经理面试、HR面试。在Mybatis中,InterceptorChain中有一个属性拦截器,里面存放了所有Mybatis插件,执行插件时会遍历拦截器。A插件->B插件->C插件……总结起来就是上面提到的8种设计模式。其实Mybatis中还有更多的设计模式,比如组合模式、迭代器模式等。对于文中的8种设计模式,我建议一个优先级,从高到低:Singleton->Factory->TemplateMethod->代理->装饰器->责任链->适配器->构建器。前五个人强烈推荐掌握。本文转载自微信公众号《Java后端技术全栈》,可通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。
