点一下关注吧!!!非常感谢!!持续更新!!!
大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html
目前已经更新到了:
- MyBatis(正在更新)
基本介绍
MyBatis 中用到了如下的设计模式:
- 建造者模式:SqlSessionFactoryBuilder、Environment
- 工厂方法模式:SqlSessionFactory、TransactionFactory、LogFactory
- 单例模式:ErrorContext、LogFactory
- 代理模式:MapperProxy、ConnectionLogger
- 组合模式:SqlNode、ChooseSqlNode
- 模板方法方式:BaseExecutor、SimpleExecutor
- 适配器模式:Log
- 装饰者模式:Cache
- 迭代起模式:PropertyTokenizer
具体如下图所示:
建造者模式
概念介绍
该模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式和 Builder 模式,相对于工厂模式会产出一个完整的产品,Builder 应用与更加复杂的对象构建,甚至只会构建产品的一个部分。
简单来说,就是通过简单的对象来一步一步构建复杂的对象。
简单案例
比如要组装一台电脑,我们需要:
- 主机
- 显示器
- 键盘
- 鼠标
- 音响
此时我们 :
- 目标类
- 构建类
- 依次创建部件
- 组装结果
编写代码
WzkComputer
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WzkComputer {private String displayer;private String mouse;private String keyword;private String sound;}
WzkComputerBuilder
package icu.wzk.design.builder;import javafx.util.Builder;public class WzkComputerBuilder {private WzkComputer wzkComputer = new WzkComputer();public WzkComputerBuilder installDisplay(String displayName) {wzkComputer.setDisplayer(displayName);return this;}public WzkComputerBuilder installMouse(String mouseName) {wzkComputer.setMouse(mouseName);return this;}public WzkComputerBuilder installKeyboard(String keyboardName) {wzkComputer.setKeyword(keyboardName);return this;}public WzkComputerBuilder installSound(String soundName) {wzkComputer.setSound(soundName);return this;}public WzkComputer build() {return wzkComputer;}
}
WzkBuilderTest
package icu.wzk.design.builder;public class WzkBuilderTest {public static void main(String[] args) {WzkComputer wzkComputer = new WzkComputerBuilder().installDisplay("三星").installMouse("罗技").installKeyboard("罗技").installSound("破喇叭").build();System.out.println(wzkComputer);}}
测试运行
执行上述的 WzkBuilderTest,控制台输出结果如下:
WzkComputer(displayer=三星, mouse=罗技, keyword=罗技, sound=破喇叭)
Process finished with exit code 0
对应的截图如下所示:
MyBatis 的体现
SqlSessionFactory 的构建过程:MyBatis 的初始化工作非常复杂,不是只用了一个构造函数就能搞定的,所以使用了建造者模式,使用了大量的 Builder,进行分层构造,核心对象是 Configuration,使用了 XMLConfigBuilder 来进行构造。
在 MyBatis 环境的初始化过程中,SqlSessionFactoryBuilder 会调用 XMLConfigBuilder 读取所有的 MyBatisMapConfig.xmk 和 所有的 mapper.xml 文件。
private void parseConfiguration(XNode root) {try {// Issue #117: Read properties first// Parse <properties /> tagpropertiesElement(root.evalNode("properties"));// Parse <settings /> tagProperties settings = settingsAsProperties(root.evalNode("settings"));// Load custom VFS implementation classloadCustomVfs(settings);// Parse <typeAliases /> tagtypeAliasesElement(root.evalNode("typeAliases"));// Parse <plugins /> tagpluginElement(root.evalNode("plugins"));// Parse <objectFactory /> tagobjectFactoryElement(root.evalNode("objectFactory"));// Parse <objectWrapperFactory /> tagobjectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));// Parse <reflectorFactory /> tagreflectorFactoryElement(root.evalNode("reflectorFactory"));// Set <settings /> to Configuration propertysettingsElement(settings);// Issue #631: Read it after objectFactory and objectWrapperFactory// Parse <environments /> tagenvironmentsElement(root.evalNode("environments"));// Parse <databaseIdProvider /> tagdatabaseIdProviderElement(root.evalNode("databaseIdProvider"));} catch (Exception e) {// Handle exceptionse.printStackTrace();}
}
其次,在 XMLConfigBuilder 在构建 Configuration 对象时,也会调用 XMLMapperBuilder 用于读取 Mapper 文件,而 XMLMapperBuilder 会使用 XMLStatementBuilder 来读取和 build 所有 SQL 语句。
可以看到 SqlSessionFactoryBuilder 类根据不同的参数输入参数来构建,这么多的工作不是一个构造函数能够完成的。
工厂模式
概念介绍
在 MyBatis 中比如 SqlSessionFactory 使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂模式。
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于创建型模式。
在简单工厂模式中,可以根据参数的不同返回不同类的实例,简单工厂模式专门定义了一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单案例
假设有一个电脑的生产商,之前能生产联想电脑,随着业务的发展,现在可以生成惠普电脑了。我们可以用简单工厂来实现。
编写代码
WzkComputer
package icu.wzk.design.factory;public abstract class WzkComputer {public abstract void start();}
LenovoComputer
package icu.wzk.design.factory;import icu.wzk.design.factory.WzkComputer;public class LenovoComputer extends WzkComputer {@Overridepublic void start() {System.out.println("生产联想电脑");}
}
HpComputer
package icu.wzk.design.factory;public class HpComputer extends WzkComputer {@Overridepublic void start() {System.out.println("生产惠普电脑");}
}
ComputerFactory
package icu.wzk.design.factory;import icu.wzk.design.factory.WzkComputer;public class ComputerFactory {public static WzkComputer createComputer(String type) {switch (type) {case "lenovo":return new LenovoComputer();case "hp":return new HpComputer();default:throw new IllegalArgumentException("Invalid computer type: " + type);}}}
WzkComputerTest
package icu.wzk.design.factory;public class WzkComputerTest {public static void main(String[] args) {ComputerFactory.createComputer("lenovo").start();ComputerFactory.createComputer("hp").start();}}
测试运行
控制台输出的内容如下所示:
MyBatis 的体现
MyBatis 中执行 SQL 语句,获取 Mappers,管理事务的核心接口 SqlSession 的创建过程使用到了工厂模式。
可以看到有很多的重载方法,DefaultSqlSessionFactory 中有默认的工厂实现。