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

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

1. 工厂模式(Factory Pattern)

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

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

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 实例。

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

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 语句模板来实现类似功能。

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 执行过程。

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 机制使用装饰器模式,可以在运行时动态地添加插件。

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 进行处理。

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 执行过程。

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 对象。

public interface SqlCommand {
    String getSql();

    Integer getUpdateCount();

    boolean isSelect();

    void clear();
}

启发

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

对工作或学习的启发

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

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

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值