设计模式之——组合模式

1 定义

组合模式:Composite Pattern,也叫合成模式或部分-整体模式。将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式主要是用来描述“部分与整体”的关系。
组合模式通用类图:


设计模式之——组合模式_第1张图片
组合模式通用类图
  • Component抽象构件角色
    定义参加组合对象的公有方法和属性,可以定义一些默认的行为或属性。一般为接口或者抽象类。
  • Leaf叶子构件
    叶子对象,下面不再有其他的分支,是遍历的最小单位。
  • Composite树枝构件
    树枝对象,作用是组合树枝节点和叶子节点来形成一个树形结构。

2 组合模式通用代码示例

  1. 抽象构件
    抽象构件是组合模式的核心。
@Slf4j
public abstract class Component {
    /**
     * 个体和整体都具有的共享方法
     */
    public void operation() {
        //基础业务逻辑
        log.info("抽象构件业务逻辑。---{}", this.getClass().getSimpleName());
    }
}
  1. 树枝构件
    树枝构件是组合模式的重点。
@Slf4j
public class Composite extends Component {
    /**
     * 构件容器
     */
    private List 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 getChilden() {
        return this.components;
    }
}
  1. 叶子构件
    叶子构件没有子对象,定义了参加组合的原始对象行为。
@Slf4j
public class Leaf extends Component {

//    /**
//     * 可以覆写父类的方法
//     */
//    @Override
//    public void operation() {
//        super.operation();
//    }

    /**
     * 叶子节点自己的业务逻辑
     */
    public void selfMethod() {
        //叶子节点自己的业务逻辑
        log.info("{}.selfMethod()", this.getClass().getSimpleName());
    }
}
  1. 场景类
    场景类负责构建树状结构和遍历。
@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 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 优点

  1. 高层模块调用简单
    一棵树中所有节点都是Component,局部和整体对调用者来说没有区别。高层模块不必关心自己处理的是单个对象还是整个组合结构,简化高层模块代码。
  2. 节点自由增加
    如果想增加一个树枝节点,只要找到它的父节点就可以了,非常容易扩展,符合"开闭原则"。对以后的维护非常有利。

3.2 缺点

不符合依赖倒置原则:在场景类中,直接使用了树叶和树枝的实现类,没有使用面向接口编程。

4 组合模式的使用场景和注意事项

4.1 使用场景

  1. 维护和展示"部分-整体关系"的场景
    树形结构,如属性菜单,文件/文件夹管理等场景。
  2. 从一个整体中能够独立出部分模块或功能的场景。

参考

  1. 设计模式之禅

你可能感兴趣的:(设计模式之——组合模式)