点一下关注吧!!!非常感谢!!持续更新!!!
大数据篇正在更新!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 /> tag
propertiesElement(root.evalNode("properties"));
// Parse <settings /> tag
Properties settings = settingsAsProperties(root.evalNode("settings"));
// Load custom VFS implementation class
loadCustomVfs(settings);
// Parse <typeAliases /> tag
typeAliasesElement(root.evalNode("typeAliases"));
// Parse <plugins /> tag
pluginElement(root.evalNode("plugins"));
// Parse <objectFactory /> tag
objectFactoryElement(root.evalNode("objectFactory"));
// Parse <objectWrapperFactory /> tag
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
// Parse <reflectorFactory /> tag
reflectorFactoryElement(root.evalNode("reflectorFactory"));
// Set <settings /> to Configuration property
settingsElement(settings);
// Issue #631: Read it after objectFactory and objectWrapperFactory
// Parse <environments /> tag
environmentsElement(root.evalNode("environments"));
// Parse <databaseIdProvider /> tag
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
} catch (Exception e) {
// Handle exceptions
e.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 {
@Override
public void start() {
System.out.println("生产联想电脑");
}
}
HpComputer
package icu.wzk.design.factory;
public class HpComputer extends WzkComputer {
@Override
public 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 中有默认的工厂实现。