设计模式之——组合模式
2019-03-10 本文已影响0人
Jerry_1116
1 定义
组合模式:Composite Pattern,也叫合成模式或部分-整体模式。将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式主要是用来描述“部分与整体”的关系。
组合模式通用类图:
组合模式通用类图
- Component抽象构件角色
定义参加组合对象的公有方法和属性,可以定义一些默认的行为或属性。一般为接口或者抽象类。 - Leaf叶子构件
叶子对象,下面不再有其他的分支,是遍历的最小单位。 - Composite树枝构件
树枝对象,作用是组合树枝节点和叶子节点来形成一个树形结构。
2 组合模式通用代码示例
- 抽象构件
抽象构件是组合模式的核心。
@Slf4j
public abstract class Component {
/**
* 个体和整体都具有的共享方法
*/
public void operation() {
//基础业务逻辑
log.info("抽象构件业务逻辑。---{}", this.getClass().getSimpleName());
}
}
- 树枝构件
树枝构件是组合模式的重点。
@Slf4j
public class Composite extends Component {
/**
* 构件容器
*/
private List<Component> components = new ArrayList<>();
/**
* 增加一个叶子构件或树枝构件
*
* @param component 叶子构件或树枝构件
*/
public void add(Component component) {
this.components.add(component);
}
/**
* 删除叶子构件或树枝构件
*
* @param component 叶子构件或树枝构件
*/
public void remove(Component component) {
this.components.remove(component);
}
/**
* 获得分支下的所有叶子构件和树枝构件
*
* @return 分支下的所有叶子构件和树枝构件
*/
public List<Component> getChilden() {
return this.components;
}
}
- 叶子构件
叶子构件没有子对象,定义了参加组合的原始对象行为。
@Slf4j
public class Leaf extends Component {
// /**
// * 可以覆写父类的方法
// */
// @Override
// public void operation() {
// super.operation();
// }
/**
* 叶子节点自己的业务逻辑
*/
public void selfMethod() {
//叶子节点自己的业务逻辑
log.info("{}.selfMethod()", this.getClass().getSimpleName());
}
}
- 场景类
场景类负责构建树状结构和遍历。
@Slf4j
public class Client {
public static void main(String[] args) {
//创建根节点
Composite root = new Composite();
root.operation();
//创建一个树枝构件
Composite branch = new Composite();
root.add(branch);
//创建一个叶子节点
Leaf leaf = new Leaf();
branch.add(leaf);
//遍历树状结构
display(root);
}
/**
* 遍历树枝构件
*
* @param composite 树枝构件
*/
private static void display(Composite composite) {
if (Objects.isNull(composite)) {
log.warn("composite is NULL! ");
return;
}
List<Component> children = composite.getChilden();
if (children == null || children.size() == 0) {
log.warn("子节点为NULL或空! ");
return;
}
for (Component component : children) {
if (component instanceof Leaf) {
//叶子节点
component.operation();
((Leaf) component).selfMethod();
} else {
//树枝节点
display((Composite) component);
}
}
}
}
3 组合模式的优缺点
3.1 优点
- 高层模块调用简单
一棵树中所有节点都是Component,局部和整体对调用者来说没有区别。高层模块不必关心自己处理的是单个对象还是整个组合结构,简化高层模块代码。 - 节点自由增加
如果想增加一个树枝节点,只要找到它的父节点就可以了,非常容易扩展,符合"开闭原则"。对以后的维护非常有利。
3.2 缺点
不符合依赖倒置原则:在场景类中,直接使用了树叶和树枝的实现类,没有使用面向接口编程。
4 组合模式的使用场景和注意事项
4.1 使用场景
- 维护和展示"部分-整体关系"的场景
树形结构,如属性菜单,文件/文件夹管理等场景。 - 从一个整体中能够独立出部分模块或功能的场景。