组合模式
Composite design pattern helps to compose the objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
特征
- 树状结构,层级结构
- 使客户端,对待个体和组合整体统一,没有任何差别
UML
image.png组件
Component
- declares the interface for objects in the composition.
- implements default behavior for the interface common to all classes, as appropriate.
- declares an interface for accessing and managing its child components.
Leaf
- represents leaf objects in the composition. A leaf has no children.
- defines behavior for primitive objects in the composition.
Composite
- defines behavior for components having children.
- stores child components.
- implements child-related operations in the Component interface.
Client
- manipulates objects in the composition through the Component interface.
在这个 UML 图中,客户端使用 Component 接口来和这个层级的组合进行交互。在层级内部,如果对象是组合,他就把请求传递给自己的叶子节点,如果这个对象是叶子节点,这个请求将被立即执行。
组合叶子节点还可以选择在叶子节点处理请求之前或之后修改请求/响应。
总结
- 复合模式定义了由单个对象和复合对象组成的类层次结构。
- 客户端通过组件接口统一处理原语和复合对象,这使得客户端代码简单。
- 添加新组件很容易,而且客户端代码不需要更改,因为客户端通过component接口处理新组件。
- 可以使用迭代器设计模式遍历复合层次结构。
- 访问者设计模式可以对组合进行操作。
- Flyweight设计模式通常与Composite组合在一起实现共享叶节点。
场景
抽象组件(组织)
抽象组件定义了组件的通知接口,并实现了增删子组件及获取所有子组件的方法。同时重写了hashCode和equales方法。
public abstract class Organization {
private List<Organization> childOrgs = new ArrayList<Organization>();
private String name;
public Organization(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addOrg(Organization org) {
childOrgs.add(org);
}
public void removeOrg(Organization org) {
childOrgs.remove(org);
}
public List<Organization> getAllOrgs() {
return childOrgs;
}
public abstract void inform(String info);
@Override
public int hashCode(){
return this.name.hashCode();
}
@Override
public boolean equals(Object org){
if(!(org instanceof Organization)) {
return false;
}
return this.name.equals(((Organization) org).name);
}
简单组件(部门)
简单组件在通知方法中只负责对接收到消息作出响应。
public class Department extends Organization{
public Department(String name) {
super(name);
}
private static Logger LOGGER = LoggerFactory.getLogger(Department.class);
public void inform(String info){
LOGGER.info("{}-{}", info, getName());
}
}
复合组件(公司)
复合组件在自身对消息作出响应后,还须通知其下所有子组件
public class Company extends Organization{
private static Logger LOGGER = LoggerFactory.getLogger(Company.class);
public Company(String name) {
super(name);
}
public void inform(String info){
LOGGER.info("{}-{}", info, getName());
List<Organization> allOrgs = getAllOrgs();
allOrgs.forEach(org -> org.inform(info+"-"));
}
}
MyBatis 中的应用
- MyBatis 在处理动态 SQL 点时,应用到了组合设计模式。 MyBatis 会将动态 SQL 点解析成对应的 SqlNode 实现,并形成树形结构。
网友评论