当前位置: 首页 > news >正文

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

组合模式

  • 描述
    • 基本使用
      • 所有节点方法一致
        • 使用
      • 叶子无实现子节点
        • 使用
    • 添加向上查询
        • 使用(没变化)

描述

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

基本使用

所有节点方法一致

  • 定义通用操作抽象组件
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();
}
  • 定义树枝节点
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;}
}
  • 定义叶子节点
public class LeafComponent extends AbstractComponent {protected LeafComponent(String name) {super(name);}@Overridepublic void addItem(AbstractComponent child) {}@Overridepublic void deleteItem(AbstractComponent child) {}@Overridepublic List<AbstractComponent> getChildren() {return null;}
}
使用

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

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();}});}
}

叶子无实现子节点

  • 定义通用操作的抽象组件
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 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;}
}
  • 定义叶子节点
public class LeafComponent extends AbstractComponent {protected LeafComponent(String name) {super(name);}
}
使用
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();}});}
}

添加向上查询

在有的场景中,需要支持向上查询。
可以在通用抽象中定义一个上级节点,然后在父节点添加子节点同时为子节点关联父节点

  • 定义通用抽象组件
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;}
}
  • 定义树枝节点
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;}
}
  • 定义叶子节点(没变化)
public class LeafComponent extends AbstractComponent {protected LeafComponent(String name) {super(name);}@Overridepublic void addItem(AbstractComponent child) {}@Overridepublic void deleteItem(AbstractComponent child) {}@Overridepublic List<AbstractComponent> getChildren() {return null;}
}
使用(没变化)
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();}});}
}

相关文章:

  • Unity SpriteMask(精灵遮罩)
  • Go 语言中一个功能强大且广泛使用的数据验证库github.com/go-playground/validator/v10
  • Js扩展DOM、BOM、AJAX、事件、定时器
  • 系统架构设计师:设计模式概述
  • 为 Unity 项目添加自定义 USB HID 设备支持 (适用于 PC 和 Android/VR)-任何手柄、无人机手柄、摇杆、方向盘
  • 补题( Convolution, 二维卷积求输出矩阵元素和最大值)
  • 华为云Astro大屏连接器创建操作实例:抽取物联网iotda影子设备数据的连接器创建
  • 【中间件】bthread_基础_TaskControl
  • Kotlin革新数据分析
  • linux 使用nginx部署next.js项目,并使用pm2守护进程
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(六)
  • 快速上手非关系型数据库-MongoDB
  • 使用Node编写轻量级后端快速入门
  • UDP数据包和TCP数据包的区别;网络编程套接字;不同协议的回显服务器
  • WPF采集欧姆龙PLC、基恩士PLC、西门子PLC、汇川PLC、台达PLC数据
  • WPF实现数据库操作与日志记录
  • 2025年- H17-Lc125-73.矩阵置零(矩阵)---java版
  • MySQL 查找指定表名的表的主键
  • Kubernetes(k8s)的API Server 组件原理与结合生产实战教程
  • 【LeetCode Hot100】回溯篇
  • 韩国检方结束对尹锡悦私宅的扣押搜查
  • 工业富联一季度净利增长25%,云计算业务营收增长超50%
  • 神十九飞船已撤离空间站,计划于今日中午返回东风着陆场
  • 普京与卢卡申科举行会晤,将扩大在飞机制造等领域合作
  • 上海科创的三种品格
  • 专访|首夺天元头衔创生涯历史,王星昊打算一步一步慢慢来