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

设计模式14-组合模式

定义

        Composite Partern:将对象组合成树形结构以表示“部分-整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

场景

  • 处理树形结构数据:如文件系统(文件和文件夹)、组织架构(部门和员工)、菜单系统(菜单项和子菜单)等。

  • 需要统一操作单个对象和组合对象:当客户端代码需要对「单个元素」和「元素集合」执行相同操作时(如计算总大小、展示信息等)。

  • 动态构建层次结构:需要灵活地增加 / 删除层级节点,且不影响客户端对结构的使用。

代码

import java.util.ArrayList;
import java.util.List;// 组合节点:复合部门(可以包含子部门)
public class CompositeDepartment implements DepartmentComponent {private String name;private List<DepartmentComponent> children = new ArrayList<>();public CompositeDepartment(String name) {this.name = name;}@Overridepublic void add(DepartmentComponent component) {children.add(component);}@Overridepublic void remove(DepartmentComponent component) {children.remove(component);}@Overridepublic void display(int depth) {// 显示部门信息,并递归显示所有子部门StringBuilder sb = new StringBuilder();for (int i = 0; i < depth; i++) {sb.append("  ");}sb.append("+ ").append(name).append(" (总员工数: ").append(getEmployeeCount()).append(")");System.out.println(sb.toString());// 递归显示子部门for (DepartmentComponent child : children) {child.display(depth + 1);}}@Overridepublic int getEmployeeCount() {// 计算本部门总员工数(所有子部门员工数之和)int total = 0;for (DepartmentComponent child : children) {total += child.getEmployeeCount();}return total;}@Overridepublic String getName() {return name;}
}// 部门组件接口:定义所有部门组件的共同行为
interface DepartmentComponent {// 添加子部门void add(DepartmentComponent component);// 移除子部门void remove(DepartmentComponent component);// 显示部门信息void display(int depth);// 获取部门员工数量int getEmployeeCount();// 获取部门名称String getName();
}// 叶子节点:基础部门(不能包含子部门)
class LeafDepartment implements DepartmentComponent {private String name;private int employeeCount;public LeafDepartment(String name, int employeeCount) {this.name = name;this.employeeCount = employeeCount;}@Overridepublic void add(DepartmentComponent component) {// 叶子节点不能添加子部门throw new UnsupportedOperationException("基础部门不能包含子部门");}@Overridepublic void remove(DepartmentComponent component) {// 叶子节点没有子部门可移除throw new UnsupportedOperationException("基础部门没有子部门可移除");}@Overridepublic void display(int depth) {// 显示部门信息,使用depth控制缩进StringBuilder sb = new StringBuilder();for (int i = 0; i < depth; i++) {sb.append("  ");}sb.append("- ").append(name).append(" (员工数: ").append(employeeCount).append(")");System.out.println(sb.toString());}@Overridepublic int getEmployeeCount() {return employeeCount;}@Overridepublic String getName() {return name;}
}// 演示部门树形结构的使用
class DepartmentHierarchyDemo {public static void main(String[] args) {// 创建公司顶级部门CompositeDepartment company = new CompositeDepartment("总公司");// 创建一级部门CompositeDepartment techDepartment = new CompositeDepartment("技术部");CompositeDepartment marketingDepartment = new CompositeDepartment("市场部");CompositeDepartment adminDepartment = new CompositeDepartment("行政部");// 向技术部添加二级部门techDepartment.add(new LeafDepartment("前端开发组", 12));techDepartment.add(new LeafDepartment("后端开发组", 18));// 创建三级部门结构CompositeDepartment productDepartment = new CompositeDepartment("产品研发中心");productDepartment.add(new LeafDepartment("产品设计组", 5));productDepartment.add(new LeafDepartment("测试组", 8));productDepartment.add(new LeafDepartment("运维组", 6));// 将产品研发中心添加到技术部(成为二级部门)techDepartment.add(productDepartment);// 向市场部添加二级部门marketingDepartment.add(new LeafDepartment("市场推广组", 6));marketingDepartment.add(new LeafDepartment("销售组", 20));// 向行政部添加二级部门adminDepartment.add(new LeafDepartment("人力资源组", 4));adminDepartment.add(new LeafDepartment("财务组", 5));adminDepartment.add(new LeafDepartment("行政后勤组", 3));// 将一级部门添加到公司company.add(techDepartment);company.add(marketingDepartment);company.add(adminDepartment);// 展示整个部门层级结构System.out.println("公司部门层级结构:");company.display(0);}
}

组合模式代码

http://www.dtcms.com/a/361118.html

相关文章:

  • 内存管理 - 从虚拟到物理
  • ADSL 代理 Proxy API 申请与使用指南
  • 前端安全防护深度实践:从XSS到CSRF的完整安全解决方案
  • T507 音频调试
  • 在 Qt 中:QString 好,还是 std::string 好?
  • DVWA靶场通关笔记-Weak Session IDs (Impossible级别)
  • 【Flask】测试平台开发,实现全局邮件发送工具 第十二篇
  • 【SpringBoot】20 - SpringBoot中的Ajax和MyBatis究竟是什么?
  • 【lucene核心】impacts的由来
  • 【Web安全】CRLF注入攻击深度解析:原理、场景与安全测试防御指南
  • hive表不显示列注释column comment的问题解决
  • 【Proteus仿真】蜂鸣器控制系列仿真——蜂鸣器控制/蜂鸣器播放音乐/蜂鸣器播放多种音乐/蜂鸣器和LED组成报警装置
  • UE5 C++ 第三方动态库的使用
  • 【数据库】openGauss 6.0 单机自动化安装最佳实践
  • MTK-Android13-实现拷贝预置资源到vendor分区下
  • Java全栈学习笔记27
  • 深度解析条件编译:#ifdef与#ifndef的本质区别与应用实践
  • Dify中使用SearXNG
  • 子串:滑动窗口最大值
  • Macbook Air M4 笔记本 ChatTTS 初体验
  • 总线矩阵的原理
  • 番外篇 | YOLO-FireAD:通过注意力逆残差模块与双池化模块融合实现高精度火灾检测
  • GitHub CLI (gh) 全面指南:终端中的 GitHub 工作流革命
  • 前端页面性能优化
  • JavaScript 性能优化实战技术
  • 99、23种设计模式之组合模式(8/23)
  • Map + 函数式接口的策略模式
  • 控制系统仿真之PID校正-利用PID控制器、PID调节器实现(九)
  • Coze源码分析-工作空间-项目开发-后端源码
  • Python爬虫实战:研究 Lines, bars and markers 模块,构建电商平台数据采集和分析系统