设计模式简述(十四)组合模式

组合模式

描述

组合模式用于描述部分与整体的关系,将个体对象与组合对象的行为统一,便于维护整个数据集。

基本使用

所有节点方法一致

  • 定义通用操作抽象组件
java 复制代码
public abstract class AbstractComponent {
    private final String name;

    protected AbstractComponent(String name) {
        this.name = name;
    }

    public void description() {
        System.out.println("name: " + this.name);
    }

    public abstract void addItem(AbstractComponent child);

    public abstract void deleteItem(AbstractComponent child);

    public abstract List<AbstractComponent> getChildren();
}
  • 定义树枝节点
java 复制代码
public class ComplexComponent extends AbstractComponent {
    private final List<AbstractComponent> children = new ArrayList<>();

    protected ComplexComponent(String name) {
        super(name);
    }

    public void addItem(AbstractComponent child) {
        children.add(child);
    }

    public void deleteItem(AbstractComponent child) {
        children.remove(child);
    }

    public List<AbstractComponent> getChildren() {
        return children;
    }
}
  • 定义叶子节点
java 复制代码
public class LeafComponent extends AbstractComponent {
    protected LeafComponent(String name) {
        super(name);
    }

    @Override
    public void addItem(AbstractComponent child) {

    }

    @Override
    public void deleteItem(AbstractComponent child) {

    }

    @Override
    public List<AbstractComponent> getChildren() {
        return null;
    }
}
使用

由于所有节点操作一致,在使用中无需强转

java 复制代码
public class Sample {
    public static void main(String[] args) {
        AbstractComponent root = new ComplexComponent("L1");
        AbstractComponent l2 = new ComplexComponent("L2");
        root.addItem(l2);
        AbstractComponent l2_1 = new ComplexComponent("L2_1");
        AbstractComponent l2_2 = new ComplexComponent("L2_2");
        l2.addItem(l2_1);
        l2.addItem(l2_2);
        AbstractComponent l2_1_1 = new ComplexComponent("L2_1_1");
        l2_1.addItem(l2_1_1);
        AbstractComponent l2_1_2 = new ComplexComponent("L2_1_2");
        l2_1.addItem(l2_1_2);
        printComponent(root);
    }

    private static void printComponent(AbstractComponent root) {
        root.description();
        root.getChildren().forEach(component -> {
            if (component instanceof ComplexComponent) {
                printComponent(component);
            } else {
                component.description();
            }
        });
    }
}

叶子无实现子节点

  • 定义通用操作的抽象组件
java 复制代码
public abstract class AbstractComponent {
    private final String name;

    protected AbstractComponent(String name) {
        this.name = name;
    }

    public void description() {
        System.out.println("name: " + this.name);
    }
}
  • 定义树枝节点
java 复制代码
public class ComplexComponent extends AbstractComponent {
    private final List<AbstractComponent> children = new ArrayList<>();

    protected ComplexComponent(String name) {
        super(name);
    }

    public void addItem(AbstractComponent child) {
        children.add(child);
    }

    public void deleteItem(AbstractComponent child) {
        children.remove(child);
    }

    public List<AbstractComponent> getChildren() {
        return children;
    }
}
  • 定义叶子节点
java 复制代码
public class LeafComponent extends AbstractComponent {
    protected LeafComponent(String name) {
        super(name);
    }
}
使用
java 复制代码
public class Sample {
    public static void main(String[] args) {
        ComplexComponent root = new ComplexComponent("L1");
        ComplexComponent l2 = new ComplexComponent("L2");
        root.addItem(l2);
        ComplexComponent l2_1 = new ComplexComponent("L2_1");
        ComplexComponent l2_2 = new ComplexComponent("L2_2");
        l2.addItem(l2_1);
        l2.addItem(l2_2);
        ComplexComponent l2_1_1 = new ComplexComponent("L2_1_1");
        l2_1.addItem(l2_1_1);
        ComplexComponent l2_1_2 = new ComplexComponent("L2_1_2");
        l2_1.addItem(l2_1_2);
        printComponent(root);
    }

    private static void printComponent(ComplexComponent root) {
        root.description();
        root.getChildren().forEach(component -> {
            if (component instanceof ComplexComponent) {
                printComponent((ComplexComponent) component);
            } else {
                component.description();
            }
        });
    }
}

添加向上查询

在有的场景中,需要支持向上查询。

可以在通用抽象中定义一个上级节点,然后在父节点添加子节点同时为子节点关联父节点

  • 定义通用抽象组件
java 复制代码
public abstract class AbstractComponent {
    private final String name;
    /**
     * 新增了一个父级成员
     */
    private AbstractComponent parent;

    protected AbstractComponent(String name) {
        this.name = name;
    }

    public void description() {
        System.out.println("name: " + this.name + "  parent: " + (Objects.isNull(getParent()) ? "null" : getParent().getName()));
    }

    public abstract void addItem(AbstractComponent child);

    public abstract void deleteItem(AbstractComponent child);
    public abstract List<AbstractComponent> getChildren();

    public void setParent(AbstractComponent parent) {
        this.parent = parent;
    }

    public AbstractComponent getParent() {
        return parent;
    }

    public String getName() {
        return name;
    }
}
  • 定义树枝节点
java 复制代码
public class ComplexComponent extends AbstractComponent {
    private final List<AbstractComponent> children = new ArrayList<>();

    protected ComplexComponent(String name) {
        super(name);
    }

    /**
     * 在添加子节点时 同时设置子节点的父级节点
     * @param child
     */
    public void addItem(AbstractComponent child) {
        children.add(child);
        child.setParent(this);
    }

    /**
     * 在移除子节点时 同时清空子节点的父级节点
     * @param child
     */
    public void deleteItem(AbstractComponent child) {
        children.remove(child);
        child.setParent(null);
    }

    public List<AbstractComponent> getChildren() {
        return children;
    }
}
  • 定义叶子节点(没变化)
java 复制代码
public class LeafComponent extends AbstractComponent {
    protected LeafComponent(String name) {
        super(name);
    }

    @Override
    public void addItem(AbstractComponent child) {

    }

    @Override
    public void deleteItem(AbstractComponent child) {

    }

    @Override
    public List<AbstractComponent> getChildren() {
        return null;
    }
}
使用(没变化)
java 复制代码
public class Sample {
    public static void main(String[] args) {
        AbstractComponent root = new ComplexComponent("L1");
        AbstractComponent l2 = new ComplexComponent("L2");
        root.addItem(l2);
        AbstractComponent l2_1 = new ComplexComponent("L2_1");
        AbstractComponent l2_2 = new ComplexComponent("L2_2");
        l2.addItem(l2_1);
        l2.addItem(l2_2);
        AbstractComponent l2_1_1 = new ComplexComponent("L2_1_1");
        l2_1.addItem(l2_1_1);
        AbstractComponent l2_1_2 = new ComplexComponent("L2_1_2");
        l2_1.addItem(l2_1_2);
        printComponent(root);
    }

    private static void printComponent(AbstractComponent root) {
        root.description();
        root.getChildren().forEach(component -> {
            if (component instanceof ComplexComponent) {
                printComponent(component);
            } else {
                component.description();
            }
        });
    }
}
相关推荐
NG47712 小时前
【软件设计与体系结构】-策略设计模式
java·设计模式·软件工程
CaffeinePro13 小时前
SOLID五大设计原则:重构优雅代码与架构的底层规范
设计模式·架构
饮茶三千14 小时前
电子保函模板编辑器实战二:HTML→FTL 编译转换的设计与实现
前端·vue.js·设计模式
Kel14 小时前
Node.js 本质:从全脉络视角理解运行时原理
javascript·设计模式·node.js
码哥字节16 小时前
11 万 Star 的 Spec Kit,90% 的工程师只用它解决了 10% 的问题
设计模式·vibe coding·github spec kit
我登哥MVP16 小时前
走进 Gang of Four 设计模式:访问者模式
java·设计模式·访问者模式·原型模式
ttod_qzstudio17 小时前
【软考设计模式】状态模式:状态驱动行为自动转换与代码填空精讲
设计模式·状态模式
饮茶三千18 小时前
基于 WangEditor 的富文本编辑器定制实践
前端·vue.js·设计模式
ttod_qzstudio19 小时前
【软考设计模式】中介者模式:网状交互的解耦与集中调度精讲
设计模式·中介者模式
饼干哥哥2 天前
一夜之间,全世界的 Agent 能力提高了一个档次
设计模式·agent·代码规范