Java设计模式:组合模式

❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注点赞收藏评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉

文章目录

  • 一、组合模式的定义
  • 二、组合模式的结构
  • 三、组合模式的实现
  • 四、组合模式的分类
  • 五、组合模式的优缺点
  • 六、组合模式的使用场景

一、组合模式的定义

组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成 树状结构 以表示 “部分-整体”的层次结构。通过组合模式,客户端可以统一对待单个对象和组合对象,使得用户在使用单个对象和组合对象时无需区分它们的差异。


二、组合模式的结构

组合模式包含以下的重要角色:

  • 抽象根节点(Component): 定义了抽象类或接口,声明了组件对象的通用接口,包括对叶子节点和容器节点的操作。
  • 容器节点(Composite): 实现了Component接口的容器节点对象,它包含叶子节点和/或其他容器节点,具有对子节点进行管理的能力。
  • 叶子节点(Leaf): 实现了Component接口的叶子节点对象,它是组合中的最小单位,不能包含其他子节点。

三、组合模式的实现

需求案例:在公司的组织架构管理系统中,可以包含公司、部门、员工级别,现在需要展示出公司的层级结构,因此使用组合模式来描述公司的层级结构,我们的需求是打印出公司所包含的部门以及员工。

树形结构如下:
在这里插入图片描述

 

使用组合模式实现上述案例,类图如下:
在这里插入图片描述
 
具体的类设计如下:

组件接口:

public abstract class OrganizationComponent {private String name;private String description;public OrganizationComponent(String name, String description) {this.name = name;this.description = description;}public String getName() {return name;}public String getDescription() {return description;}// 叶子节点不需要实现,故不定义成抽象方法,而是采用默认实现protected void add(OrganizationComponent organizationComponent) {// 默认实现throw new UnsupportedOperationException();}protected void remove(OrganizationComponent organizationComponent) {// 默认实现throw new UnsupportedOperationException();}// 抽象方法print(),子类都需要实现protected abstract void print();
}

容器节点(公司):

public class Company extends OrganizationComponent {private List<OrganizationComponent> subComponents = new ArrayList<>();public Company(String name, String description) {super(name, description);}public void addComponent(OrganizationComponent component) {subComponents.add(component);}public void removeComponent(OrganizationComponent component) {subComponents.remove(component);}@Overrideprotected void print() {System.out.println(getName() + "(" + getDescription() + ")");for (OrganizationComponent component : subComponents) {component.print();}}
}

容器节点(部门):

public class Department extends OrganizationComponent {private List<OrganizationComponent> subComponents = new ArrayList<>();public Department(String name, String description) {super(name, description);}public void addComponent(OrganizationComponent component) {subComponents.add(component);}public void removeComponent(OrganizationComponent component) {subComponents.remove(component);}@Overrideprotected void print() {System.out.println("- " + getName() + "(" + getDescription() + ")");for (OrganizationComponent component : subComponents) {component.print();}}
}

叶子节点(员工):

public class Employee extends OrganizationComponent {public Employee(String name, String description) {super(name, description);}@Overrideprotected void print() {System.out.println("-- " + getName() + "(" + getDescription() + ")");}
}

客户端类:

public class client {public static void main(String[] args) {Employee emp1 = new Employee("张三", "软件工程师");Employee emp2 = new Employee("李四", "UI设计师");Department engineering = new Department("工程部", "开发部门");engineering.addComponent(emp1);engineering.addComponent(emp2);Employee emp3 = new Employee("王五", "市场专员");Employee emp4 = new Employee("赵六", "销售代表");Department marketing = new Department("市场部", "市场部门");marketing.addComponent(emp3);marketing.addComponent(emp4);Company myCompany = new Company("xxx公司", "科技发展有限公司");myCompany.addComponent(engineering);myCompany.addComponent(marketing);// 显示公司组织结构myCompany.print();}}

测试结果如下:
在这里插入图片描述


四、组合模式的分类

在使用组合模式时,根据组件的角色和结构的复杂性,我们可将组合模式分为透明组合模式和安全组合模式两种形式。

  • 透明组合模式(Transparent Composite Pattern):
    在透明组合模式中,抽象组件(Component)类中声明了所有用于管理子对象的方法,包括添加、移除和获取子对象等。具体叶子节点和容器节点都继承自抽象组件,并实现这些方法。这样客户端对于叶子节点和容器节点无需区分,可以统一使用。

  • 安全组合模式(Safe Composite Pattern):
    在安全组合模式中,抽象组件(Component)类中不声明用于管理子对象的方法,而是在具体叶子节点和容器节点中进行实现。这样客户端需要区分叶子节点和容器节点,使用时需要注意调用正确的方法。

选择透明组合模式还是安全组合模式取决于应用的需求和设计的考虑。透明组合模式提供了更统一的接口,但可能暴露一些对于叶子节点不适用的方法,而安全组合模式更加安全,但客户端需要更多的责任来判断调用的正确方法。


五、组合模式的优缺点

优点:

  1. 统一接口: 组合模式通过使用统一的接口,使得客户端可以一致地处理单个对象和组合对象,简化了客户端的代码。
  2. 灵活性: 可以通过组合模式构建复杂的 树形结构,使得系统具有更高的灵活性和可扩展性。可以随时添加新的叶子节点或容器节点,而不需要修改已有的代码。
  3. 可重用性: 叶子节点和容器节点的组合关系使得这些节点可以被重复使用,促进了代码的重用。
  4. 简化客户端代码: 客户端无需关心处理单个对象还是组合对象,可以简化客户端代码,提高代码的可维护性。

缺点:

  1. 可能过于一般化: 在某些情况下,组合模式可能过于一般化,不容易满足特定的需求。例如,可能会导致在叶子节点和容器节点上都定义了一些对于某个节点类型不适用的操作。
  2. 可能导致性能问题: 在处理大型树形结构时,组合模式可能导致性能问题,因为递归地处理整个结构可能会引起性能开销。
  3. 难以限制组件类型: 组合模式难以限制组件类型,因为客户端对于叶子节点和容器节点的操作是一致的。这可能导致在不同类型的组件上执行不适用的操作。

六、组合模式的使用场景

  1. 树形结构: 当系统中的对象具有部分-整体的层次结构,并且可以表示为树形结构时,适合使用组合模式。例如,组织架构、文件系统等都可以使用组合模式来表示。
  2. 管理和操作集合对象: 当需要对集合对象以统一的方式进行管理和操作时,可以考虑使用组合模式。这样可以统一处理单个对象和组合对象,无需区分它们的差异。
  3. 用户界面元素: 在构建用户界面时,可能存在层级嵌套的元素,如面板、按钮、复选框等。使用组合模式可以方便地管理和操作这些用户界面元素。
  4. 文件和文件夹管理: 文件系统中的文件和文件夹也是典型的组合结构。组合模式可以用于处理文件和文件夹之间的关系,统一操作这些对象。
  5. 组件化设计: 在软件设计中,当需要构建可重用的组件并且这些组件之间存在层次关系时,可以考虑使用组合模式。这有助于提高组件的灵活性和可扩展性。
  6. 部门-整体关系的场景: 任何具有部分-整体关系的场景都可能适合使用组合模式。例如,汽车的部件组装、家具的装配等都可以考虑使用组合模式。

 
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 分享👥 留言💬thanks!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/497763.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用pyannote-audio实现声纹分割聚类

使用pyannote-audio实现声纹分割聚类 # GitHub地址 https://github.com/MasonYyp/audio1 简单介绍 pyannote.audio是用Python编写的用于声纹分割聚类的开源工具包。在PyTorch机器学习基础上&#xff0c;不仅可以借助性能优越的预训练模型和管道实现声纹分割聚类&#xff0c;还…

【React 报错】—Remove untracked files, stash or commit any changes, and try again.

【React 报错】—Remove untracked files, stash or commit any changes, and try again. 在react项目中通过.less文件进行样式定义&#xff0c;先暴露webpack配置文件&#xff0c;执行命令&#xff1a;yarn eject 或 npm run eject&#xff0c;报错如下&#xff1a; 原因是因…

掌握关键生活细节,让小脑萎缩患者的生活更美好

在这个充满变数的世界里&#xff0c;小脑萎缩患者的生活似乎更加充满挑战。但只要用心&#xff0c;生活的每一个角落都能绽放出不一样的光彩。今天&#xff0c;就让我们一起走进小脑萎缩患者的日常&#xff0c;探索他们需要注意的事项&#xff0c;共同守护这份温暖而坚韧的生活…

二叉搜索树在线OJ题讲解

二叉树创建字符串 我们首先进行题目的解读&#xff1a; 大概意思就是用&#xff08;&#xff09;把每个节点的值给括起来&#xff0c;然后再经过一系列的省略的来得到最后的结果 大家仔细观察题目给出的列子就可以发现&#xff0c;其实这个题目可以大致分为三种情况&#xff1…

Qt5转Qt6笔记

背景 现在的主程序和扩展的dll库都是qt5环境下编译发布的。但是想以后用qt6。所以考虑是否能够在qt5中兼容qt6的动态链接库进行加载。于是...就开始吧 开始 2024-02-23 安装好qt6后&#xff0c;在vs2019中需要新增qt6版本的安装路径。目录在&#xff1a;扩展->QT VS Tools…

LeetCode 2125.银行中的激光束数量

银行内部的防盗安全装置已经激活。给你一个下标从 0 开始的二进制字符串数组 bank &#xff0c;表示银行的平面图&#xff0c;这是一个大小为 m x n 的二维矩阵。 bank[i] 表示第 i 行的设备分布&#xff0c;由若干 ‘0’ 和若干 ‘1’ 组成。‘0’ 表示单元格是空的&#xff0…

opencv中两个LSD直线检测算法的区别与应用

opencv中两个LSD直线检测算法的区别与应用 同样是Line Segment Detector(lsd)算法&#xff0c;opencv中提供了两种实现&#xff0c;并且位于不同的模块。下面分别介绍它们的使用方法&#xff1a; 1. LineSegmentDetector 由于源码许可证问题 OpenCV 3.4.6-3.4.15、4.1.0-4.5.…

vue中使用prettier

前言&#xff1a;prettier是一款有态度的代码格式化工具&#xff0c;它可以集成在IDE中&#xff0c;如VS Code、Web Storm等&#xff0c;也可以安装到我们开发的项目里面。本文主要讲解在Vue中集成prettier的过程&#xff0c;可以便于代码检测和格式化。 prettier官网 从官网的…

【论文笔记】Attention Is All You Need

【论文笔记】Attention Is All You Need 文章目录 【论文笔记】Attention Is All You NeedAbstract1 Introduction2 Background补充知识&#xff1a;软注意力 soft attention 和硬注意力 hard attention&#xff1f;补充知识&#xff1a;加法注意力机制和点乘注意力机制Extende…

MFC教程 -- Windows界面开发

MFC教程 -- Windows界面开发 Windows消息机制 初步认识MFC 要想熟练掌握 Windows 应用程序的开发&#xff0c; 首先需要理解 Windows 平台下程序运行的内部机制。如果想要更好的学习掌握 MFC&#xff0c;必须要先了解Windows 程序的内部运行机制&#xff0c;为我们扫清学习路…

【Java程序设计】【C00327】基于Springboot的高校教师教研信息填报系统(有论文)

基于Springboot的高校教师教研信息填报系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校教师教研信息填报系统&#xff0c;本系统有管理员、教研管理以及教研人员三种角色&#xff1b; 管理员&#xff1a…

【DAY05 软考中级备考笔记】线性表,栈和队列,串数组矩阵和广义表

线性表&#xff0c;栈和队列&#xff0c;串数组矩阵和广义表 2月28日 – 天气&#xff1a;阴转晴 时隔好几天没有学习了&#xff0c;今天补上。明天发工资&#xff0c;开心&#x1f604; 1. 线性表 1.1 线性表的结构 首先线性表的结构分为物理结构和逻辑结构 物理结构按照实…