设计模式(三)-结构型模式(4)-组合模式

2023-12-19

一、为何需要组合模式(Composite)?

在代码设计中,有种情况是对象之间存在层次关系,即对象之间会存在父结点和子结点的关系。

比如在文件管理系统中,所有文件和文件夹形成树状结构,文件夹目录里存在子文件夹和文件。文件夹属于枝结点,文件属于叶结点。枝结点有下一个层级,所以可以对其子结点的对象进行移除或增加新对象的操作。而叶结点并没有移除和增加的操作,是因为它没有子结点。

对于这种对象之间存在的层级关系,我们可以使用组合模式来设计。

特点:

将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。(一致性:如文件夹和文件都有被打开的操作。所有文件夹对其子结点都有移除和增加新子结点的操作。)

结构:

组合对象的抽象接口(Component):定义组合对象的公共接口。(组合对象指的是所有结点。如文件系统的打开,移除和增加的功能接口)
叶结点具体类(Leaf):叶结点实现组合对象的抽象方法,但没有子结点。(如文件)
枝结点具体类(Composite):枝节点实现组合对象的抽象方法,并且有一个容器用来存储子结点。(如文件夹)

适合应用场景特点:

  • 对象之间存在层次结构,具有使用某些功能的一致性。

请添加图片描述

二、例子

需求:

一家公司里的部门有人事部、开发部、测试部、设计部。现在该公司又把测试部再分为软件测试组和硬件测试组。每个测试组都有一个组长。每当完成某个阶段任务时,公司要求每个部门以及测试部组长进行汇报工作进度的情况。

设计分析:

  • 枝结点:公司、人事部、开发部、设计部、测试部、软件测试组、硬件测试组。叶结点:软件测试组长和硬件测试组长。
  • 所有结点的公共动作:汇报工作。
  • 所有树枝结点都有增加和移除结点的操作。

1、定义组合对象的抽象接口:


    //Component:(组合对象的抽象接口,叶结点抽象接口)
    public abstract class Company
    {
        public string Name { get; protected set; }
        public abstract void reportWork();
    }

    //Component:(组合对象的抽象接口,枝结点抽象接口)
    public abstract class AbsComposite : Company
    {
        public abstract void Add(Company company);
        public abstract void Remove(Company company);
    }

2、定义叶结点具体类和枝结点具体类:


//Leaf:叶结点具体类(组长、同事成员)
    public class GroupLeader : Company
    {
        public GroupLeader(string name)
        {
            Name = name;
        }
        public override void reportWork()
        {
            Console.WriteLine(Name);
        }
    }

    //Composite:枝结点具体类(公司、部门)
    public class Composite : AbsComposite
    {
        private List<Company> _CompanyList = new List<Company>();//容器
        public List<Company> CompanyList { get { return _CompanyList; } }

        public Composite(string name)
        {
            this.Name = name;
        }

        public override void Add(Company company)
        {
            _CompanyList.Add(company);
        }

        public override void Remove(Company company)
        {
            _CompanyList.Remove(company);
        }

        public override void reportWork()
        {
            Console.WriteLine("The following members need to report their work to our company:");
            getCompanyList(CompanyList);
        }

        //不是组合对象的公共接口,是 Department 类私有的成员方法。
        //该方法是为了测试例子而用的,并不是学习组合模式的要点。可忽略。
        private void getCompanyList(List<Company> list)
        {
            foreach (var item in list)
            {

                var itemDepart = item as Composite;//枝结点
                if (itemDepart != null)
                {
                    if (itemDepart.CompanyList?.Count > 0)
                    {
                        Console.WriteLine();
                        Console.Write("【" + item.Name +"】" + "-");枝结点,有子结点
                        getCompanyList(itemDepart.CompanyList);
                        continue;
                    }

                    Console.WriteLine("【" + item.Name + "】");//枝结点,子结点为空
                }
                else
                    Console.Write("(" + item.Name + ")");//叶结点

            }

        }

    }

3、主程序:


    //主程序
    class Program
    {
        static void Main(string[] args)
        {
            AbsComposite root = new Composite("阳光组合公司");
            root.Add(new Composite("人事部"));
            root.Add(new Composite("开发部"));
            root.Add(new Composite("设计部"));
            
            var testDepartment = new Composite("测试部");
            var software = new Composite("软件测试组");
            var hardware = new Composite("硬件测试组");
            GroupLeader softwareLeader = new GroupLeader("软件测试组长");
            GroupLeader hardwareLeader = new GroupLeader("硬件测试组长");

            root.Add(testDepartment);
            testDepartment.Add(software);
            testDepartment.Add(hardware);
            software.Add(softwareLeader);
            hardware.Add(hardwareLeader);

            root.reportWork();//各部门和测试组长汇报工作

            Console.ReadLine();
        }
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式(三)-结构型模式(4)-组合模式 的相关文章

  • Spring源码学习之BeanDefinition源码解析

    本文作者 磊叔 GLMapper本文链接 https juejin cn post 6844903553820000269 Bean的定义主要由BeanDefinition来描述的 作为Spring中用于包装Bean的数据结构 今天就来看看
  • c++享元模式

    享元模式 1 享元模式简介 享元模式在 设计模式 可复用面向对象软件的基础 一书中是这样说的 运用共享技术有效地支持大量细粒度的对象 本质就是对大量细粒度的对象进行共享 不是每个对象都要通过new的方式去创建 而是通过区分对象的内部状态和外
  • 常用设计模式总结

    设计模式的相关知识 很多书籍和博客中都有详细总结 本文总结的目的 1 将自己学习到的设计模式的知识按照自己的逻辑重新总结 方便查看和记忆 2 方便让自己对设计模式中常用的知识有一个系统的认知 设计模式 话设计模式 书中提到 24 种设计模式
  • 设计模式-单一职责原则介绍与理解

    描述 一个类应该专注于实现一个功能 好处 便于代码复用 举例 俄罗斯方块游戏 首先可以想到的是游戏逻辑与界面的分离 也就是说逻辑一个类 界面部分一个类 这样做的好处就是我们可以复用游戏逻辑的代码 例如我们用java写了一个基于PC端的俄罗斯
  • C++设计模式-State状态模式

    State状态模式作用 当一个对象的内在状态改变时允许改变其行为 这个对象看起来像是改变了其类 UML图如下 State类 抽象状态类 定义一个接口以封装与Context的一个特定状态相关的行为 ConcreteState类 具体状态 每一
  • 行为型模式-状态模式

    package per mjn pattern state after 环境角色类 public class Context 定义对应状态对象的常量 public final static OpeningState OPENING STAT
  • 设计模式一之简单工厂模式

    生活示例 刻板印刷 gt 活字印刷举例 喝酒唱歌 人生真爽 gt 对酒当歌 人生几何 可维护 需要修改 则只需要改需要改的字即可 可复用 字体可在后来的印刷复用 可扩展 需要加字 只需要加入相应的刻字即可 灵活性好 字的排列可能竖排或横排
  • 设计模式-建造者模式

    文章目录 建造者模式 创建复杂对象的优雅方式 什么是建造者模式 建造者模式的使用场景 优缺点 示例 使用建造者模式创建电脑对象 建造者模式 创建复杂对象的优雅方式 在软件开发中 有时候我们需要创建具有复杂结构和多个组件的对象 直接在客户端代
  • 设计模式(5)-适配器模式(Adapter Pattern)

    适配器模式 Adapter Pattern 顾名思义 就像变压器 转接头差不多 就像美国的生活电压是110V 中国是220V 就需要一个变压器将220V转换成110V 或者一个Type C接口想插如USB接口的东西 你就需要一个转换器 而这
  • 第12课:生活中的构建模式——想要车还是庄园

    用程序来模拟生活 从剧情中思考构建模式 与工厂模式的区别 与组合模式的区别 构建模式的模型抽象 类图 基于升级版的实现 模型说明 应用场景 故事剧情 下周就要过年了 这是 Tony 工作后的第一个春节 还是在离家这么远的北京工作 所以肯定不
  • 每日一问:你想如何破坏单例模式?

    前言 1 单例是什么 单例模式 是一种创建型设计模式 目的是保证全局一个类只有一个实例对象 分为懒汉式和饿汉式 所谓懒汉式 类似于懒加载 需要的时候才会触发初始化实例对象 而饿汉式正好相反 项目启动 类加载的时候 就会创建初始化单例对象 1
  • HeadFirst 设计模式学习笔记10——MVC分析

    1 M V C Model View Controller 模式 视图 控制器 这是一种范型 模型对象正是应用系统存在的理由 你设计的对象 包含了数据 逻辑和其他在你的应用领域创建定制的类 视图通常是控件 用来显示和编辑 控制器位于二者中间
  • 单例模式的八种写法比较

    单例模式是最常用到的设计模式之一 熟悉设计模式的朋友对单例模式都不会陌生 一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式 但是除了这两种方式 本文还会介绍其他几种实现单例的方式 让我们来一起看看吧 简介 单例模式是一种常
  • Java设计模式之装饰者设计模式Decorator Pattern

    目录 一 基本概念 二 结构 1 图示 三 案例演示 被装饰对象的基类 一个接口 有cost 和description 两个抽象方法 具体被装饰的对象 实现上面这个接口 装饰者抽象类 基类 实现drink接口 具体的装饰者类 糖 具体装饰者
  • 组合型模式

    概述 对于这个图片肯定会非常熟悉 上图我们可以看做是一个文件系统 对于这样的结构我们称之为树形结构 在树形结构中可以通过调用某个方法来遍历整个树 当我们找到某个叶子节点后 就可以对叶子节点进行相关的操作 可以将这颗树理解成一个大的容器 容器
  • 设计模式(2)

    2 2 结构型模式 结构型模式一共有七种 其中 适配器模式和装饰模式统称为包装模式 装饰模式和代理模式的类图基本相同 但目的不同 这些有相似目的或者有相似结构的模式需要对其概念辨析清楚 才能较好地掌握 下面将对结构型模式分别进行介绍 2 2
  • Java监听器与观察者模式

    Java监听器与观察者模式 Java中的监听器 Listener 和观察者模式 Observer Pattern 都是用于处理对象间的事件通知和响应的设计模式 它们的目的是在对象之间建立一种松散的耦合 使得一个对象的状态变化可以通知到其他对
  • 设计模式详解---策略模式

    1 策略模式简介 策略模式 Strategy Pattern 是一种行为型设计模式 用于在运行时根据不同的情境选择不同的算法或策略 该模式将算法封装成独立的类 使得它们可以相互替换 而且可以独立于客户端使用它们的方式 1 1 主要角色 上下
  • 设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

    原创 疯狂的狮子Li 狮子领域 程序圈 2023 12 19 10 30 发表于辽宁 原型模式 原型模式 Prototype模式 是指 用原型实例指定创建对象的种类 并且通过拷贝这些原型 创建新的对象 原型模式是一种创建型设计模式 允许一个
  • 【设计模式之美】理论一:怎么才算是单一原则、如何取舍单一原则

    文章目录 一 如何判断类的职责是否足够单一 二 类的职责是否设计得越单一越好 开始学习一些经典的设计原则 其中包括 SOLID KISS YAGNI DRY LOD 等 本文主要学习单一职责原则的相关内容 单一职责原则的定义 一个类只负责完

随机推荐

  • 持续集成交付CICD:K8S 自动化完成前端项目应用发布与回滚

    目录 一 实验 1 环境 2 GitLab新建项目存放K8S部署文件 3 Jenkins手动测试前端项目CD 流水线代码 下载部署文件 4 将K8S master节点配置为jenkins从节点 5 K8S 手动回滚前端项目版本 6 Jenk
  • 《LeetCode力扣练习》代码随想录——双指针法(替换数字---Java)

    LeetCode力扣练习 代码随想录 双指针法 替换数字 Java 刷题思路来源于 代码随想录 54 替换数字 受制于语言限制 普通解法 import java util Scanner class Main public static v
  • Set系列集合

    Set系列集系概述 Set系列集合特点 无序 存取顺序不一致 不重复 可以去除重复 无索引 没有带索引的方法 所以不能使用普通for循环遍历 也不能通过索引来获取元素 Set集合的功能上基本上与Collection的API一致 Set集合实
  • 想学习了解渗透测试?看完这一篇就够了

    一 什么是渗透测试 渗透测试 也称为笔测试 是针对计算机系统的模拟网络攻击 以检查可利用的漏洞 在这样的背景下Web 应用程序安全性方面 渗透测试通常用于增强 Web 应用程序防火墙 WAF 笔测试可能涉及尝试破坏任意数量的应用程序系统 例
  • 【功能更新】支持文档合并导出PDF/HTML格式;线上文章SEO设置能力优化

    HelpLook 功能更新速览 文档管理能力 1 导出支持多篇文档合在一个HTML文件 2 支持下载附件时保留原始文件名 3 主页 推荐文章 支持添加外链 4 文章URL根据标题自动生成 5 文章支持添加 作者 6 博客模版支持置顶文章 1
  • python打包exe failed to execute,python打包成exe 用不了

    本篇文章给大家谈谈python打包的exe有的电脑不能运行 以及python文件打包成exe文件运行报错 希望对各位有所帮助 不要忘了收藏本站喔 大家好 给大家分享一下一个有趣的事情 很多人还不知道这一点 下面详细解释一下 python t
  • Windows7系统ntoskrnl.exe文件丢失问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个ntoskrn
  • Python Plotly交互可视化详解

    今天给大家分享一篇可视化干货 介绍的是功能强大的开源 Python 绘图库 Plotly 教你如何用超简单的 甚至只要一行 代码 绘制出更棒的图表 沉没成本谬误 是人们常犯的几种认知偏差之一 由于在某件事上已经投入了 沉没 太多的成本 即使
  • 论文查重率太低怎么改能高一点 papergpt

    大家好 今天来聊聊论文查重率太低怎么改能高一点 希望能给大家提供一点参考 以下是针对论文重复率高的情况 提供一些修改建议和技巧 可以借助此类工具 论文查重率太低怎么改能高一点 在撰写论文时 有时会遇到查重率过低的问题 智能写作 这通常是因为
  • App(Android)ICP备案号查询——————高仿微信

    个人主页 拉莫帅 CSDN博客 博文 132篇 原创 130篇 转载 2篇 总阅读量 388923 粉丝量 112 感谢点赞和关注 每天进步一点点 加油 目录 工业和信息化部关于开展移动互联网应用程序备案工作的通知 1 前言 2 备案收费
  • 神州信息戴可分享金融数字化转型破局之道

    近日 第二十届中国国际金融论坛在中国上海拉开帷幕 在 金融科技赋能服务数字经济发展 为主题的平行论坛上 神州信息副总裁戴可发表 基于数云融合的AI Bank 的主题演讲 分享了公司在金融数字化转型方面的最新进展 全面阐释了 数云融合 如何助
  • 论文降重助手同义词替换 papergpt

    大家好 今天来聊聊论文降重助手同义词替换 希望能给大家提供一点参考 以下是针对论文重复率高的情况 提供一些修改建议和技巧 可以借助此类工具 标题 论文降重助手 同义词替换的妙用 一 引言 在论文写作过程中 我们常常会遇到重复内容的问题 为了
  • 病案管理的定义、流程及应用分析

    病案管理是指针对病人的基本信息 病历 就诊记录等进行收集 整理 存储 分析和应用的一项管理工作 它在医院 医疗机构和医疗行业中具有重要的作用 能够提高医疗服务的质量 效率和安全性 本文将就病案管理的定义 流程以及其在医疗健康领域中的应用进行
  • WarAgent使用多智能体理解人类历史和预防未来国际冲突

    我们能否避免历史十字路口上的战争 这个问题已经被个人 学者 政策制定者和组织在人类历史中追寻了很长时间 在这项研究中 我们尝试根据人工智能 AI 和大型语言模型 LLM 的最新进展来回答这个问题 本文试图通过使用人工智能和大型语言模型 回答
  • [黑马程序员TypeScript笔记]------一篇就够了

    文章目录 1 TypeScript 介绍 TypeScript 是什么 TypeScript 为什么要为 JS 添加类型支持 TypeScript 相比 JS 的优势 2 TypeScript 初体验 安装编译 TS 的工具包
  • IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Spring的AOP前奏

    第一章 AOP前奏 1 1 代理模式 代理模式 我们需要做一件事情 又不期望自己亲力亲为 此时 可以找一个代理 中介 我们 目标对象 与中介 代理对象 不能相互转换 因为是 兄弟 关系 1 2 为什么需要代理 程序中 需求 实现 加减乘除
  • python单元测试框架pytest介绍

    pytest是python语言中一款强大的单元测试框架 用来管理和组织测试用例 可应用在单元测试 自动化测试工作中 unittest也是python语言中一款单元测试框架 但是功能有限 没有pytest灵活 就像 苹果电脑mac air和m
  • pytest测试框架+allure超详细教程

    1 测试识别和运行 文件识别 在给定的目录中 搜索所有test py或者 test py文件 用例识别 Test 类包含的所有test 的方法 测试类不能有 init 方法 不在类中的所有test 方法 pytest也能执行unit tes
  • 计算机毕业设计选题推荐-SpringBoot 毕业就业信息管理系统

    作者主页 疯狂行者 java领域优质创作者 专注于Java技术领域技术交流 文末获取源码 精彩专栏推荐订阅 在 下方专栏 Java精彩实战项目案例 Java精彩新手项目案例 Python精彩新手项目案例 文章目录 Java精彩实战项目案例
  • 设计模式(三)-结构型模式(4)-组合模式

    一 为何需要组合模式 Composite 在代码设计中 有种情况是对象之间存在层次关系 即对象之间会存在父结点和子结点的关系 比如在文件管理系统中 所有文件和文件夹形成树状结构 文件夹目录里存在子文件夹和文件 文件夹属于枝结点 文件属于叶结