MyBatis 中的 9 种设计模式及其代码示例

MyBatis 是一个流行的 Java 持久层框架,它通过使用设计模式来提高代码的灵活性、可维护性和可扩展性。以下是 MyBatis 中常见的 9 种设计模式的全面剖析,包括代码示例和它们对我们工作或学习的启发。

1. 工厂模式(Factory Pattern)

定义:定义创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

应用示例 : 在 MyBatis 中,SqlSessionFactory 是通过工厂模式创建的。SqlSessionFactoryBuilder 是一个工厂类,它负责构建 SqlSessionFactory 实例。

java 复制代码
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

启发

  • 在实际开发中,使用工厂模式可以避免硬编码对象的创建逻辑,使得代码更加灵活和可维护。
2. 单例模式(Singleton Pattern)

定义:保证一个类只有一个实例,并提供一个全局访问点。

应用示例SqlSessionFactory 是一个典型的单例。每个 MyBatis 应用通常只需要一个 SqlSessionFactory 实例。

java 复制代码
public class SqlSessionFactoryBuilder {
    private static SqlSessionFactory instance;

    public static synchronized SqlSessionFactory build(InputStream inputStream) {
        if (instance == null) {
            instance = new SqlSessionFactory(new Configuration(inputStream));
        }
        return instance;
    }
}

启发

  • 单例模式确保了资源的共享和一致性,适用于需要全局访问点的场景。
3. 建造者模式(Builder Pattern)

定义:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

应用示例SqlSessionFactoryBuilder 使用建造者模式构建 SqlSessionFactory

java 复制代码
public class SqlSessionFactoryBuilder {
    private Configuration configuration;

    public SqlSessionFactoryBuilder(Configuration configuration) {
        this.configuration = configuration;
    }

    public SqlSessionFactory build() {
        return new SqlSessionFactory(configuration);
    }
}

启发

  • 建造者模式使得对象的构建过程更加清晰和灵活,适用于创建复杂对象的场景。
4. 原型模式(Prototype Pattern)

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

应用示例: 虽然 MyBatis 没有直接使用原型模式,但可以通过复制 SQL 语句模板来实现类似功能。

java 复制代码
public class SqlStatement {
    private String sql;

    public SqlStatement(String sql) {
        this.sql = sql;
    }

    public SqlStatement copy() {
        return new SqlStatement(this.sql);
    }
}

启发

  • 原型模式可以快速复制对象,适用于需要频繁创建相似对象的场景。
5. 适配器模式(Adapter Pattern)

定义:将一个类的接口转换成客户端所期待的另一种接口。

应用示例MapperProxy 是一个适配器,它将 Mapper 接口的方法调用适配到实际的 SQL 执行过程。

java 复制代码
public class MapperProxy<T> implements InvocationHandler {
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.isDefault()) {
            return invokeDefaultMethod(proxy, method, args);
        }
        return sqlSession.selectOne(method.getName(), args[0]);
    }

    private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(this, args);
    }
}

启发

  • 适配器模式可以解决接口不兼容的问题,使得不同接口的对象可以协同工作。
6. 装饰器模式(Decorator Pattern)

定义:动态地给一个对象添加额外的职责。

应用示例 : MyBatis 的 Plugin 机制使用装饰器模式,可以在运行时动态地添加插件。

java 复制代码
public interface Plugin {
    Object intercept(Invocation invocation) throws Throwable;

    default Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    static Object wrap(Object target, Plugin plugin) {
        if (target instanceof Executor) {
            return new ExecutorProxy(target, plugin);
        }
        return null;
    }
}

启发

  • 装饰器模式可以在不修改原有代码的情况下增强对象的功能,提高代码的可扩展性。
7. 观察者模式(Observer Pattern)

定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。

应用示例 : MyBatis 的 Executor 在执行 SQL 时,会通知相关的 Interceptor 进行处理。

java 复制代码
public interface Interceptor {
    Object intercept(Invocation invocation) throws Throwable;

    default Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    static Object wrap(Object target, Interceptor interceptor) {
        if (target instanceof Executor) {
            return new ExecutorProxy(target, interceptor);
        }
        return null;
    }
}

启发

  • 观察者模式可以实现对象间的解耦,使得一个对象的状态变化可以自动通知其他依赖对象。
8. 代理模式(Proxy Pattern)

定义:为其他对象提供一种代理以控制对这个对象的访问。

应用示例MapperProxy 是一个代理,它将 Mapper 接口的方法调用代理到实际的 SQL 执行过程。

java 复制代码
public class MapperProxy<T> implements InvocationHandler {
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.isDefault()) {
            return invokeDefaultMethod(proxy, method, args);
        }
        return sqlSession.selectOne(method.getName(), args[0]);
    }

    private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(this, args);
    }
}

启发

  • 代理模式可以控制对对象的访问,增加额外的处理逻辑,提高系统的安全性和灵活性。
9. 命令模式(Command Pattern)

定义:将一个请求或操作封装为一个对象,从而使用户可用不同的请求、队列或日志请求来参数化其他对象。

应用示例 : MyBatis 的 Executor 使用命令模式,每个 SQL 执行请求都被封装为一个 SqlCommand 对象。

java 复制代码
public interface SqlCommand {
    String getSql();

    Integer getUpdateCount();

    boolean isSelect();

    void clear();
}

启发

  • 命令模式可以将请求封装为对象,使得请求的发送者和接收者解耦,提高系统的灵活性和可扩展性。

对工作或学习的启发

  1. 提高代码的可维护性:通过使用设计模式,代码结构更加清晰,易于理解和维护。
  2. 增强代码的可扩展性:设计模式使得在不修改原有代码的情况下,可以灵活地扩展功能。
  3. 解耦和复用:设计模式有助于将系统的不同部分解耦,提高代码的复用性。
  4. 应对复杂性:在面对复杂的系统设计时,设计模式提供了一种结构化的方法来处理复杂性。
  5. 促进团队协作:设计模式作为一种通用语言,有助于团队成员之间的沟通和协作。

通过学习和应用这些设计模式,可以更有效地解决实际问题,提高软件的质量和性能。

相关推荐
Mr. zhihao2 小时前
深入解析 Spring Boot 中 MyBatis 自动配置的流程
spring boot·后端·mybatis
zero_one_Machel3 小时前
leetcode5最长回文子串
java·数据结构·算法
WineMonk3 小时前
设计模式 11 享元模式
设计模式·享元模式
2401_862886783 小时前
游卡,三七互娱,得物,顺丰,快手,oppo,莉莉丝,康冠科技,途游游戏,埃科光电25秋招内推
java·c语言·前端·python·算法
莫莫向上成长3 小时前
Java基础——方法引用、单元测试、XML、注解
xml·java·单元测试
要小鑫呐4 小时前
http方法调用接口
java·网络·网络协议·http
一年找不到工作就去厂里大螺丝4 小时前
SpringBoot项目目录介绍(SpringBoot学2)
java·spring boot·spring
Kwanvin4 小时前
仿华为车机UI--图标从Workspace拖动到Hotseat同时保留图标在原来位置
android·java·ui·华为·launcher3
BIGSHU09234 小时前
GPT带我学-设计模式-责任链模式
gpt·设计模式·责任链模式
神码兄弟4 小时前
## 已解决:亲测有效的 `java.nio.charset.CoderMalfunctionError` 编码器故障错误解决方法
java·开发语言·nio