结构型模式3.组合模式

news2025/1/10 23:45:15

结构型模式

  1. 适配器模式(Adapter Pattern)
  2. 桥接模式(Bridge Pattern)
  3. 组合模式(Composite Pattern)
  4. 装饰器模式(Decorator Pattern)
  5. 外观模式(Facade Pattern)
  6. 享元模式(Flyweight Pattern)
  7. 代理模式(Proxy Pattern)

组合模式(Composite Pattern) 是一种结构型设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以统一对待单个对象和对象集合,即把对象当作单一对象来处理,从而简化了操作和使用的复杂性。

核心思想:

组合模式将对象组合成树形结构,并允许客户端通过统一的接口对待单一对象和对象组合。其本质是树形结构中的每个节点可能是单个对象,也可能是对象的组合(集合)。客户端通过同一接口处理这些对象,从而达到简化代码和增强灵活性的目的。

主要角色:

  1. Component(组件):定义了一个接口,声明了基本的操作(如 add()remove()getChild() 等),这使得单个对象和组合对象(即树枝)都能使用相同的操作。
  2. Leaf(叶子节点):表示树的叶子节点(即最基本的对象),没有子节点,实现了组件接口。
  3. Composite(组合节点):表示树的枝节点(即含有子节点的对象),实现了组件接口,并且能管理子组件。组合节点可以添加、删除和获取子组件。

示例:公司组织结构

假设我们有一个公司组织结构,其中有员工(叶子节点)和经理(组合节点),经理可以有下属员工或者其他经理。这种组织结构非常适合使用组合模式来实现。

// 组件接口
public interface Employee {
    void showDetails(); // 显示员工信息
}

// 叶子节点,代表普通员工
public class RegularEmployee implements Employee {
    private String name;
    private String position;

    public RegularEmployee(String name, String position) {
        this.name = name;
        this.position = position;
    }

    @Override
    public void showDetails() {
        System.out.println("姓名: " + name + ", 职位: " + position);
    }
}

import java.util.ArrayList;
import java.util.List;

// 组合节点,代表经理(可以包含员工或其他经理)
public class Manager implements Employee {
    private String name;
    private String position;
    private List<Employee> subordinates; // 下属

    public Manager(String name, String position) {
        this.name = name;
        this.position = position;
        subordinates = new ArrayList<>();
    }

    public void addSubordinate(Employee employee) {
        subordinates.add(employee);
    }

    public void removeSubordinate(Employee employee) {
        subordinates.remove(employee);
    }

    @Override
    public void showDetails() {
        System.out.println("姓名: " + name + ", 职位: " + position);
        System.out.println("下属: ");
        for (Employee e : subordinates) {
            e.showDetails(); // 递归调用
        }
    }
}

public class Client {
    public static void main(String[] args) {
        // 创建叶子节点(普通员工)
        Employee employee1 = new RegularEmployee("张三", "开发工程师");
        Employee employee2 = new RegularEmployee("李四", "设计师");

        // 创建组合节点(经理)
        Manager manager1 = new Manager("王五", "经理");
        Manager manager2 = new Manager("赵六", "高级经理");

        // 经理1有下属员工
        manager1.addSubordinate(employee1);
        manager1.addSubordinate(employee2);

        // 经理2有经理1作为下属
        manager2.addSubordinate(manager1);

        // 展示组织结构
        System.out.println("经理2的详细信息:");
        manager2.showDetails();
    }
}

解释:

  • Employee(组件):定义了一个接口,所有的员工都实现了这个接口,不管是普通员工还是经理。
  • RegularEmployee(叶子节点):普通员工,不能有下属,实现了 Employee 接口。
  • Manager(组合节点):经理有下属员工或者其他经理。它也实现了 Employee 接口,并且能够管理其他员工(包括普通员工和经理)。

在客户端代码中,ManagerRegularEmployee 都通过 Employee 接口处理,使用 showDetails() 方法递归地展示组织结构。无论是单一的普通员工,还是一个包含多个员工和经理的复杂结构,客户端都可以使用相同的接口来处理它们。

装饰器模式 vs 组合模式:

  • 装饰器模式:用来动态地向一个对象添加额外的功能,通常涉及一个对象及其装饰器对象的组合。
  • 组合模式:用来将对象组织成树形结构,表示“部分-整体”的关系,使得客户端可以统一对待单个对象和对象组合。

优缺点:

优点:
  1. 透明性:客户端不需要关心对象的组成细节,所有对象(包括单一对象和组合对象)都通过相同的接口进行操作。
  2. 灵活性:通过递归组合,可以构建出复杂的树形结构,同时提供统一的操作方法。
  3. 简化代码:对于复杂的层级结构,客户端不需要针对每一层次编写单独的处理代码,减少了重复代码。
缺点:
  1. 过度设计:如果对象本身没有复杂的层次结构,使用组合模式可能会显得过于复杂。
  2. 维护困难:在某些场景下,组合模式可能导致代码结构变得非常复杂,特别是当组合对象的层次较深时。

总结:

组合模式通过递归组合的方式,将对象和对象组合统一处理,使得在处理“部分-整体”结构时,客户端代码更加简洁。它适用于具有树形结构的场景,如文件系统、组织结构、菜单结构等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ue5玩家角色添加武器。切换武器位置,手上武器放到背上。演示一下人体插槽和武器的连接。仅仅演示,实际项目不是这么用的

把第一人称资源包导进来 这就是我们枪的骨骼网格体 我们找到这个骨骼 右手添加插槽 取个名字 因为武器上也有动画&#xff0c;所有武器单独写个蓝图类 新建一个蓝图类 BP_Weapon 把枪的蓝图拖到人的静态网格体下&#xff0c;成为一个部分 选中BP_Weapon的父类套接字…

微信小程序防止重复点击事件

直接写在app.wpy里面&#xff0c;全局可以调用 // 防止重复点击事件preventActive(fn) {const self this;if (this.globalData.PageActive) {this.globalData.PageActive false;if (fn) fn();setTimeout(() > {self.globalData.PageActive true;}, 3000); //设置该时间内…

Docker入门之docker基本命令

Docker入门之docker基本命令 官方网站&#xff1a;https://www.docker.com/ 1. 拉取官方镜像并创建容器&#xff08;以redis为例&#xff09; 拉取官方镜像 docker pull redis# 如果不需要添加到自定义网络使用这个命令&#xff0c;如需要&#xff0c;直接看第二步 docker r…

SQL Server中可以通过扩展事件来自动抓取阻塞

在SQL Server中可以通过扩展事件来自动抓取阻塞&#xff0c;以下是详细流程&#xff1a; 开启阻塞跟踪配置&#xff1a; • 执行以下SQL语句来启用相关配置&#xff1a; EXEC sp_configureshow advanced options, 1; RECONFIGURE; EXEC sp_configure blocked process thresh…

【VBA】【EXCEL】将某列内容横向粘贴到指定行

Sub CopyRowToColumn()On Error GoTo ErrorHandler 添加错误处理Application.ScreenUpdating FalseApplication.Calculation xlCalculationManualApplication.EnableEvents False 禁用事件处理Dim lastCol As LongDim lastRow As LongDim i As Long, colCount As LongDim …

基于机器学习的故障诊断(入门向)

一、原始信号的特征提取 1.EMD经验模态分解的作用 信号分析&#xff1a;EMD可以将信号分解为多个IMFs&#xff0c;每个IMF代表信号中的一个特定频率和幅度调制的成分。这使得EMD能够提供对信号的时频特征进行分析的能力&#xff08;特征提取用到的&#xff09;。信号去噪&…

多台PC共用同一套鼠标键盘

当环境中有多个桌面 pc 需要操作的时候&#xff0c;在 多台 pc 之间切换会造成很多的不方便 可以通过远程进行连接&#xff0c;但是有一个更好的方案是让多台机器之间共用同一套键盘鼠标 常用的解决方案 synergy 和 sharemouse&#xff0c;通过移动光标在不同的 pc 间切换 s…

[免费]微信小程序(高校就业)招聘系统(Springboot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序(高校就业)招聘系统(Springboot后端Vue管理端)&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序(高校就业)招聘系统(Springboot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项目介绍…

Midjourney 应用:框架总结

Midjourney 应用&#xff1a;框架总结 官方的模板很简单&#xff0c;分成四个部分&#xff1a; 主体细节 & 背景风格、媒介、艺术家参数 我的总结 其实按照官方模板写&#xff0c;你已经能超过 90% 的初学者&#xff0c;但根据我的实验&#xff0c;我细化了他们的模板的…

【Maui】导航栏样式调整

前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&#xff0c;可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款开放源代码应用&#xff0c;是 X…

uniapp 微信小程序内嵌h5实时通信

描述&#xff1a; 小程序webview内嵌的h5需要向小程序实时发送消息&#xff0c;有人说postMessage可以实现&#xff0c;所以试验一下&#xff0c;结果是实现不了实时&#xff0c;只能在特定时机后退、组件销毁、分享时小程序才能接收到信息&#xff08;小程序为了安全等考虑做了…

腾讯云AI代码助手编程挑战赛-厨房助手之AI大厨

腾讯云AI代码助手编程挑战赛-厨房助手之AI大厨 作品简介 身处当今如火箭般迅猛发展的互联网时代&#xff0c;智能聊天助手已然化身成为提升用户体验的关键利器&#xff0c;全方位渗透至人们的数字生活。 紧紧跟随着这股汹涌澎湃的时代浪潮&#xff0c;我毅然投身于极具挑战性…

网易云音乐登录两部手机:IP属地归属何方?

在数字化生活日益普及的今天&#xff0c;音乐平台成为了我们日常娱乐不可或缺的一部分。网易云音乐&#xff0c;作为众多音乐爱好者的首选&#xff0c;其丰富的音乐资源和个性化的推荐算法深受用户喜爱。然而&#xff0c;随着多设备登录成为常态&#xff0c;一个问题也随之浮现…

[工具]git克隆远程仓库到本地快速操作流程

一、新建空目录 二、初始化本地仓库 git init 初始化成功后&#xff0c;会在当前目录生成一个.git的目录。 三、关联远程仓库 git remote add origin <URL>这一步让本地仓库与远程仓库进行关联&#xff0c;origin是远程仓库的别名&#xff0c;可以自定义。 四、克隆…

如何在 Ubuntu 22.04 上集成 Collabora Online 教程

简介 在本教程中&#xff0c;我们将详细讲解如何在 Ubuntu 22.04 操作系统上安装 Collabora Online。 Collabora Online 是一个基于 LibreOffice 技术的开源办公套件。它提供了许多功能&#xff0c;其中最有用的一个功能是 Collabora 提供了 Word 文档、电子表格、演示文稿等…

Linux的内核空间中的日志打印函数printk的详解;如果设置`printk` 函数的默认日志级别和是否输出到终端控制台

引言 首先&#xff0c;要知道&#xff0c;内核空间是没有printf函数的&#xff0c;printf函数是是用户空间的标准 I/O 函数&#xff0c;而不是内核空间中的。 所以在运行于内核空间的程序中(比如驱动程序)&#xff0c;是不能使用printf函数的&#xff0c;但有时候我们又需要打…

Python编程实例-特征向量与特征值编程实现

特征向量与特征值编程实现 文章目录 特征向量与特征值编程实现1、什么是特征向量2、特征向量背后的直觉3、为什么特征向量很重要?4、如何计算特征向量?4、特征向量Python实现5、可视化特征向量6、总结线性代数是许多高级数学概念的基石,广泛应用于数据科学、机器学习、计算机…

202-01-06 Unity 使用 Tip1 —— UnityHub 模块卸载重装

文章目录 1 卸载模块2 更新配置文件3 重启 UnityHub 起因&#xff1a; ​ WebGL 平台打包程序报错&#xff0c;懒得修复了&#xff0c;因此粗暴地删了重装。但是 UnityHub 不支持卸载模块&#xff0c;因此手动配置。 1 卸载模块 ​ 以 Unity 6000.0.26f1c1 为例&#xff0c;其…

Git的简单介绍与如何安装Git

文章目录 前言一、初始git1.git是什么2.为什么要使用git(出现的问题)3.git是如何解决问题的 二、git的安装与卸载1.centos系统2.ubuntu系统3.windows 三、搭建git本地环境1.创建git本地仓库2.配置用户信息 总结 前言 本文简单引入git的相关内容。 一、初始git 1.git是什么 g…

Linux 进程入门:带你走进操作系统的核心地带(1)

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 在 Linux 操作系…