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. 促进团队协作:设计模式作为一种通用语言,有助于团队成员之间的沟通和协作。

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

相关推荐
Q_19284999066 分钟前
基于Spring Boot的电影网站系统
java·spring boot·后端
老鑫安全培训32 分钟前
从安全角度看 SEH 和 VEH
java·网络·安全·网络安全·系统安全·安全威胁分析
罗政33 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第8章 插件与链路的结合:Gson插件实现
java·pdf·linq
马船长1 小时前
RCE-PLUS (学习记录)
java·linux·前端
HelloZheQ1 小时前
深入了解 Java 字符串:基础、操作与性能优化
java·python·性能优化
魔法工坊1 小时前
只谈C++11新特性 - 删除函数
java·开发语言·c++
落霞与孤鹭齐飞。。2 小时前
学生考勤系统|Java|SSM|VUE| 前后端分离
java·mysql·毕业设计·课程设计
橙子家czzj2 小时前
关于 K8s 的一些基础概念整理-补充【k8s系列之二】
java·开发语言·kubernetes
云:2 小时前
寒假准备找实习复习java基础-day1
java·开发语言
罗政2 小时前
PDF书籍《手写调用链监控APM系统-Java版》第3章 配置文件系统的建立
java·pdf·linq