组合模式的作用:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。
案例一
JDK 的 AWT(Abstract Window Toolkit),使用了组合模式。AWT 中包含了两种组件:容器组件和基本组件。
- 容器组件是 java.awt.Container 的子孙类
- 基本组件是 java.awt.Component 的子孙类
- 容器组件和基本组件都是 java.awt.Component 的子孙类
Container 类中包含了很多基本组件或容器,放在 ArrayList 中
public class Container extends Component {
private java.util.List<Component> component = new ArrayList<>();
//向容器类中添加基本组件或容器
public Component add(Component comp) {
addImpl(comp, null, -1);
return comp;
}
}
基本组件与容器组件,构成了树状结构。由于都是 Component 的子孙类,对 Component 定义的方法,访问上具有一致性
案例二
Mybatis 在处理 xml 动态 sql 中用到了组合模式。
- 抽象构建接口 SqlNode,定义了 apply 方法,根据传入参数构造 sql
public interface SqlNode {
boolean apply(DynamicContext context);
}
- 容器类 MixedSqlNode、ChooseSqlNode 实现 SqlNode 接口,List 存储 SqlNode
public class MixedSqlNode implements SqlNode {
private List<SqlNode> contents;
public MixedSqlNode(List<SqlNode> contents) {
this.contents = contents;
}
@Override
public boolean apply(DynamicContext context) {
for (SqlNode sqlNode : contents) {
sqlNode.apply(context);
}
return true;
}
}
public class ChooseSqlNode implements SqlNode {
private SqlNode defaultSqlNode;
private List<SqlNode> ifSqlNodes;
public ChooseSqlNode(List<SqlNode> ifSqlNodes, SqlNode defaultSqlNode) {
this.ifSqlNodes = ifSqlNodes;
this.defaultSqlNode = defaultSqlNode;
}
@Override
public boolean apply(DynamicContext context) {
for (SqlNode sqlNode : ifSqlNodes) {
if (sqlNode.apply(context)) {
return true;
}
}
if (defaultSqlNode != null) {
defaultSqlNode.apply(context);
return true;
}
return false;
}
}
- 其他叶子节点:TextSqlNode、StaticTextSqlNode、TrimSqlNode、SetSqlNode、WhereSqlNode ... 均是通过 apply 方法构建 SQL
SqlNode 的实现类通过容器类与叶子节点构造成树形结构,使用 apply 动态解析出完整的 SQL。
【Java学习资源】整理推荐
- 组合模式在开源代码中的应用
- 享元模式在开源代码中的应用
- 外观模式在开源代码中的应用
- 装饰器模式在开源代码中的应用
- 桥接模式在开源代码中的应用
- 适配器模式在开源代码中的应用
- 代理模式在开源代码中的应用
- 原型模式在开源代码中的应用
- 建造者模式在开源代码中的应用
- 工厂模式在开源代码中的应用
- 单例模式在开源代码中的应用
- 编码规范
- 设计模式
- 重构
- 设计原则
- 面向对象到底是什么
- 代码质量有哪些评判标准?