以下是 MyBatis 框架中涉及的 23 种设计模式的分类、技术原理及代码示例:
一、创建型模式
1. 工厂方法模式 (Factory Method)
作用:定义创建对象的接口,由子类决定实例化哪个类。
MyBatis 实现:
SqlSessionFactory
:通过SqlSessionFactoryBuilder
构建SqlSessionFactory
实例。
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream inputStream) {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);
return build(parser.parse()); // 解析配置并构建实例
}
}
// 具体实现(DefaultSqlSessionFactory)
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
@Override
public SqlSession openSession() {
return new DefaultSqlSession(configuration); // 创建会话实例
}
}
2. 抽象工厂模式 (Abstract Factory)
作用:创建一组相关或依赖的对象,而无需指定具体类。
MyBatis 实现:
Environment
:通过Environment
抽象工厂创建DataSource
和TransactionFactory
。
public class Environment {
private final String id;
private final TransactionFactory transactionFactory;
private final DataSource dataSource;
public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
this.id = id;
this.transactionFactory = transactionFactory;
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
}
3. 单例模式 (Singleton)
作用:确保一个类只有一个实例,并提供全局访问点。
MyBatis 实现:
ErrorContext
:通过线程局部变量保证每个线程拥有唯一的ErrorContext
实例。
public class ErrorContext {
private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<>();
public static ErrorContext instance() {
ErrorContext context = LOCAL.get();
if (context == null) {
context = new ErrorContext();
LOCAL.set(context);
}
return context;
}
}
4. 建造者模式 (Builder)
作用:逐步构建复杂对象,允许用户通过链式调用设置属性。
MyBatis 实现:
SqlSessionFactoryBuilder
:通过链式调用构建SqlSessionFactory
。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
5. 原型模式 (Prototype)
作用:通过克隆现有对象创建新实例。
MyBatis 实现:
MappedStatement
:通过克隆MappedStatement
创建新的语句对象。
public class MappedStatement implements Cloneable {
@Override
public MappedStatement clone() {
return (MappedStatement) super.clone(); // 浅克隆
}
}
二、结构型模式
6. 适配器模式 (Adapter)
作用:将接口转换为客户端期望的另一个接口。
MyBatis 实现:
Log
接口适配器:适配不同日志框架(如 SLF4J、Log4j)。
public class Slf4jLoggerImpl implements Log {
private final org.slf4j.Logger logger;
public Slf4jLoggerImpl(String clazz) {
logger = org.slf4j.LoggerFactory.getLogger(clazz);
}
@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
@Override
public void debug(String message) {
logger.debug(message);
}
}
7. 装饰器模式 (Decorator)
作用:动态为对象添加附加功能。
MyBatis 实现:
Cache
装饰器:为缓存添加附加功能(如淘汰策略)。
public class FifoCache implements Cache {
private final Cache delegate;
private final List<Object> keyList = new LinkedList<>();
@Override
public void putObject(Object key, Object value) {
if (keyList.size() >= size) {
Object oldestKey = keyList.remove(0);
delegate.removeObject(oldestKey); // 移除最旧元素
}
keyList.add(key);
delegate.putObject(key, value);
}
}
8. 代理模式 (Proxy)
作用:通过代理对象控制对原对象的访问。
MyBatis 实现:
- Mapper 接口代理:通过 JDK 动态代理生成 Mapper 接口的实现类。
public class MapperProxy<T> implements InvocationHandler {
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
return sqlSession.selectOne(method.getName(), args); // 调用具体方法
}
}
9. 外观模式 (Facade)
作用:为复杂子系统提供简化的接口。
MyBatis 实现:
SqlSession
:封装数据库操作,提供统一的访问接口。
public interface SqlSession {
<T> T selectOne(String statement, Object parameter);
int insert(String statement, Object parameter);
int update(String statement, Object parameter);
int delete(String statement, Object parameter);
}
10. 桥接模式 (Bridge)
作用:将抽象与实现解耦,使两者可以独立变化。
MyBatis 实现:
Transaction
接口:桥接不同事务实现(如 JDBC、JTA)。
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
}
// 具体实现(JdbcTransaction)
public class JdbcTransaction implements Transaction {
@Override
public Connection getConnection() {
return dataSource.getConnection(); // 返回 JDBC 连接
}
}
11. 组合模式 (Composite)
作用:将对象组合成树形结构,以表示“部分-整体”的层次结构。
MyBatis 实现:
SqlNode
组合:通过组合模式构建动态 SQL。
public interface SqlNode {
boolean apply(DynamicContext context);
}
// 具体节点(IfSqlNode)
public class IfSqlNode implements SqlNode {
private final String test;
private final SqlNode contents;
@Override
public boolean apply(DynamicContext context) {
if (evaluator.evaluateBoolean(test, context.getBindings())) {
contents.apply(context); // 递归应用子节点
return true;
}
return false;
}
}
12. 享元模式 (Flyweight)
作用:共享对象以减少内存占用。
MyBatis 实现:
MappedStatement
复用:通过Configuration
缓存MappedStatement
对象。
public class Configuration {
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<>();
public MappedStatement getMappedStatement(String id) {
return mappedStatements.get(id); // 从缓存获取
}
}
三、行为型模式
13. 模板方法模式 (Template Method)
作用:定义算法骨架,将某些步骤延迟到子类实现。
MyBatis 实现:
BaseExecutor
:定义数据库操作流程,子类实现具体步骤。
public abstract class BaseExecutor implements Executor {
@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds) {
// 公共逻辑(如缓存处理)
return doQuery(ms, parameter, rowBounds); // 调用子类实现
}
protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds);
}
14. 观察者模式 (Observer)
作用:定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者收到通知。
MyBatis 实现:
- 事件监听机制:通过
EventListener
监听数据库操作事件。
public interface EventListener {
void onEvent(Event event);
}
// 具体监听器(LogEventListener)
public class LogEventListener implements EventListener {
@Override
public void onEvent(Event event) {
System.out.println("Event occurred: " + event.getType());
}
}
15. 策略模式 (Strategy)
作用:定义一系列算法,并将每个算法封装起来,使它们可以互换。
MyBatis 实现:
StatementHandler
策略:根据数据库类型选择不同的 SQL 执行策略。
public interface StatementHandler {
Statement prepare(Connection connection) throws SQLException;
void parameterize(Statement statement) throws SQLException;
}
// 具体策略(SimpleStatementHandler)
public class SimpleStatementHandler implements StatementHandler {
@Override
public Statement prepare(Connection connection) {
return connection.createStatement(); // 返回简单语句
}
}
16. 命令模式 (Command)
作用:将请求封装为对象,以便用不同的请求、队列或日志参数化其他对象。
MyBatis 实现:
RoutingStatementHandler
:封装 SQL 执行命令。
public class RoutingStatementHandler implements StatementHandler {
private final StatementHandler delegate;
public RoutingStatementHandler(ExecutorType executorType, StatementHandler handler) {
this.delegate = handler;
}
@Override
public Statement prepare(Connection connection) {
return delegate.prepare(connection); // 执行具体命令
}
}
17. 责任链模式 (Chain of Responsibility)
作用:将请求的发送者和接收者解耦,使多个对象都有机会处理请求。
MyBatis 实现:
- 插件拦截器链:通过
InterceptorChain
处理插件拦截。
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target); // 依次应用拦截器
}
return target;
}
}
18. 备忘录模式 (Memento)
作用:捕获并保存对象的内部状态,以便后续恢复。
MyBatis 实现:
BoundSql
状态保存:通过BoundSql
保存 SQL 语句和参数。
public class BoundSql {
private final String sql;
private final List<ParameterMapping> parameterMappings;
public BoundSql(String sql, List<ParameterMapping> parameterMappings) {
this.sql = sql;
this.parameterMappings = parameterMappings;
}
public String getSql() {
return sql;
}
}
19. 状态模式 (State)
作用:允许对象在内部状态改变时改变行为。
MyBatis 实现:
- 事务状态管理:通过
TransactionState
管理事务的不同状态。
public enum TransactionState {
ACTIVE,
COMMITTED,
ROLLED_BACK
}
// 事务状态管理
public class Transaction {
private TransactionState state = TransactionState.ACTIVE;
public void commit() {
state = TransactionState.COMMITTED; // 修改状态
}
}
20. 访问者模式 (Visitor)
作用:在对象结构中定义新操作,而无需修改结构本身。
MyBatis 实现:
Node
访问者:通过XMLScriptBuilder
访问和修改 SQL 节点。
public interface Node {
void accept(Visitor visitor);
}
// 具体访问者(XMLScriptBuilder)
public class XMLScriptBuilder implements Visitor {
@Override
public void visit(TextNode node) {
// 处理文本节点
}
@Override
public void visit(IfSqlNode node) {
// 处理 If 节点
}
}
21. 解释器模式 (Interpreter)
作用:给定一种语言,定义其文法表示,并构建解释器来解释语言中的句子。
MyBatis 实现:
- OGNL 表达式解析:通过
OgnlCache
解析动态 SQL 中的表达式。
public class OgnlCache {
public static Object getValue(String expression, Object root) {
return Ognl.getValue(expression, root); // 解析表达式
}
}
22. 迭代器模式 (Iterator)
作用:提供一种顺序访问集合元素的方法,而无需暴露其内部表示。
MyBatis 实现:
- 结果集遍历:通过
ResultSetWrapper
遍历查询结果。
public class ResultSetWrapper {
private final ResultSet resultSet;
public Iterator<Object> iterator() {
return new ResultSetIterator(resultSet); // 返回迭代器
}
}
23. 中介者模式 (Mediator)
作用:定义一个中介对象来封装一系列对象之间的交互。
MyBatis 实现:
SqlSession
作为中介者:协调Executor
、StatementHandler
等组件之间的交互。
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
private final Executor executor;
@Override
public <T> T selectOne(String statement, Object parameter) {
return executor.query(configuration.getMappedStatement(statement), parameter, RowBounds.DEFAULT).get(0);
// 协调 Executor 执行查询
}
}
总结
MyBatis 框架通过灵活运用 23 种设计模式,实现了高扩展性、低耦合性和灵活性。这些模式覆盖了对象创建、结构组织、行为交互等各个方面,是学习 Java 框架设计的经典案例。