15.设计模式-组合模式

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

组合模式的两种实现:

  • 透明方式:在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以实现它是没有意义的。
  • 安全方式:在Component接口中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,这样做就不会出现刚才提到的问题,不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

需求


为一家在全国许多城市都有分销机构的大公司做办公管理系统,总部有人力资源、财务、运营等部门。

需求分析

  • 希望总公司的组织结构,比如人力资源部、财务部的管理功能可以复用于分公司

代码

业务类

#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructCompany{char*name;void(*add)(structCompany*,structCompany*);void(*remove)(structCompany*,structCompany*);void(*display)(structCompany*,int);void(*lineOfDuty)(structCompany*);}Company;typedefstructConcreteCompany{Company base;Company**children;intchildrenNum;}ConcreteCompany;voidConcreteCompanyAdd(Company*obj,Company*child){((ConcreteCompany*)obj)->children[((ConcreteCompany*)obj)->childrenNum++]=child;}voidConcreteCompanyRemove(Company*obj,Company*child){intn=((ConcreteCompany*)obj)->childrenNum;for(inti=0;i<n;i++){if(strcmp(((ConcreteCompany*)obj)->children[i]->name,child->name)==0){free(((ConcreteCompany*)obj)->children[i]);((ConcreteCompany*)obj)->children[i]=((ConcreteCompany*)obj)->children[((ConcreteCompany*)obj)->childrenNum-1];((ConcreteCompany*)obj)->childrenNum--;break;}}}voidConcreteCompanyDisplay(Company*obj,intdepth){for(inti=0;i<depth;i++){printf("-");}printf("%s\n",obj->name);intn=((ConcreteCompany*)obj)->childrenNum;for(inti=0;i<n;i++){((ConcreteCompany*)obj)->children[i]->display(((ConcreteCompany*)obj)->children[i],depth+1);}}voidConcreteCompanyLineOfDuty(Company*obj){intn=((ConcreteCompany*)obj)->childrenNum;for(inti=0;i<n;i++){((ConcreteCompany*)obj)->children[i]->lineOfDuty(((ConcreteCompany*)obj)->children[i]);}}Company*InitConcreteCompany(char*name){ConcreteCompany*obj=(ConcreteCompany*)malloc(sizeof(ConcreteCompany));obj->childrenNum=0;// 假设最多10个子公司和部门obj->children=(Company**)malloc(sizeof(Company*)*10);obj->base.name=name;obj->base.add=ConcreteCompanyAdd;obj->base.remove=ConcreteCompanyRemove;obj->base.display=ConcreteCompanyDisplay;obj->base.lineOfDuty=ConcreteCompanyLineOfDuty;return(Company*)obj;}typedefstructHRDepartment{Company base;}HRDepartment;voidHRDepartmentDisplay(Company*obj,intdepth){for(inti=0;i<depth;i++){printf("-");}printf("%s\n",obj->name);}voidHRDepartmentLineOfDuty(Company*obj){printf("%s 员工招聘培训管理\n",obj->name);}Company*InitHRDepartment(char*name){HRDepartment*obj=(HRDepartment*)malloc(sizeof(HRDepartment));obj->base.display=HRDepartmentDisplay;obj->base.lineOfDuty=HRDepartmentLineOfDuty;obj->base.name=name;return(Company*)obj;}typedefstructFinanceDepartment{Company base;}FinanceDepartment;voidFinanceDepartmentDisplay(Company*obj,intdepth){for(inti=0;i<depth;i++){printf("-");}printf("%s\n",obj->name);}voidFinanceDepartmentLineOfDuty(Company*obj){printf("%s 公司财务收支管理\n",obj->name);}Company*InitFinanceDepartment(char*name){FinanceDepartment*obj=(FinanceDepartment*)malloc(sizeof(FinanceDepartment));obj->base.display=FinanceDepartmentDisplay;obj->base.lineOfDuty=FinanceDepartmentLineOfDuty;obj->base.name=name;return(Company*)obj;}

客户端

隐藏子部门和分公司的区别

intmain(){Company*root=InitConcreteCompany("北京总公司");root->add(root,InitHRDepartment("总公司人力资源部"));root->add(root,InitFinanceDepartment("总公司财务部"));Company*comp=InitConcreteCompany("上海华东分公司");comp->add(comp,InitHRDepartment("华东分公司人力资源部"));comp->add(comp,InitFinanceDepartment("华东分公司财务部"));root->add(root,comp);Company*comp1=InitConcreteCompany("南京办事处");comp1->add(comp1,InitHRDepartment("南京办事处人力资源部"));comp1->add(comp1,InitFinanceDepartment("南京办事处财务部"));comp->add(comp,comp1);Company*comp2=InitConcreteCompany("杭州办事处");comp2->add(comp2,InitHRDepartment("杭州办事处人力资源部"));comp2->add(comp2,InitFinanceDepartment("杭州办事处财务部"));comp->add(comp,comp2);printf("结构图:\n");root->display(root,0);printf("职责:\n");root->lineOfDuty(root);return0;}

客户端打印:

结构图: 北京总公司 -总公司人力资源部 -总公司财务部 -上海华东分公司 --华东分公司人力资源部 --华东分公司财务部 --南京办事处 ---南京办事处人力资源部 ---南京办事处财务部 --杭州办事处 ---杭州办事处人力资源部 ---杭州办事处财务部 职责: 总公司人力资源部 员工招聘培训管理 总公司财务部 公司财务收支管理 华东分公司人力资源部 员工招聘培训管理 华东分公司财务部 公司财务收支管理 南京办事处人力资源部 员工招聘培训管理 南京办事处财务部 公司财务收支管理 杭州办事处人力资源部 员工招聘培训管理 杭州办事处财务部 公司财务收支管理

UML图

总结

  • 组合模式使用场景?
    “当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。”

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

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

相关文章

Nodejs+vue大学生二手闲置物品置换交易管理系统

文章目录摘要--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 该系统基于Node.js与Vue.js构建&#xff0c;旨在为大学生提供一个高效、安全的二手闲置物品交易平台。通过前后端分离架构&#xff0c;系统实现了…

2026年10款最佳降AI率工具推荐:论文AIGC检测轻松过关

2026年10款最佳降AI率工具推荐&#xff1a;论文AIGC检测轻松过关面对知网、维普、万方等平台日益严格的AIGC检测&#xff0c;选对降AI工具是关键。本文实测对比10款主流工具&#xff0c;帮你找到最适合的解决方案。为什么需要降AI率工具&#xff1f; 2026年&#xff0c;各高校普…

Nodejs+vue大学生兼职应聘评分管理系统h4bmt

文章目录系统概述核心功能模块技术实现亮点应用价值--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统概述 Node.jsVue大学生兼职应聘评分管理系统&#xff08;H4BMT&#xff09;是一款基于前后端分离架构的Web应…

Nodejs+vue大学生兼职招聘评价系统_b8t93

文章目录系统概述核心功能模块技术实现亮点应用价值--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统概述 Node.js与Vue.js结合的大学生兼职招聘评价系统旨在为高校学生和用人单位提供高效的兼职信息对接与信用…

2025年山东大学计算机考研复试机试真题(解题思路 + AC 代码)

2025年山东大学计算机考研复试机试真题 2025年山东大学计算机考研复试上机真题 历年山东大学计算机考研复试上机真题 历年山东大学计算机考研复试机试真题 更多学校完整题目开源地址&#xff1a;https://gitcode.com/u014339447/pgcode 百度一下pgcode 即可查看&#xff0…

导师不会告诉你的6个免费AI论文工具:1小时搞定全文告别熬夜

想知道为什么你隔壁实验室的同学总能提前交稿&#xff0c;而你还在一字一句地苦熬&#xff1f;因为他们在用一些“不该知道”的秘密武器。今天&#xff0c;我就来为你揭秘这些藏在水面之下的“学术黑科技”&#xff0c;特别是那个能让论文效率提升10倍的终极神器。 前言&#x…

输入聚食的人数,预算和口味偏好,自动推荐附近的餐厅,还能生成聚餐菜单。

智能聚餐规划系统1. 项目概述实际应用场景在朋友、同事或家庭聚会时&#xff0c;组织一次成功的聚餐需要考虑多个因素&#xff1a;人数、预算、不同人的口味偏好、餐厅选择、菜品搭配等。传统方式需要人工查询、比较、协调&#xff0c;过程繁琐且容易遗漏重要信息。痛点分析- 信…

2025年同济大学计算机考研复试机试真题(解题思路 + AC 代码)

2025年同济大学计算机考研复试机试真题 2025年同济大学计算机考研复试上机真题 历年同济大学计算机考研复试上机真题 历年同济大学计算机考研复试机试真题 更多学校完整题目开源地址&#xff1a;https://gitcode.com/u014339447/pgcode 百度一下pgcode 即可查看&#xff0…

matlab实时脚本算拉普拉斯反变换和画图

//////////////////////clcclose allclearsyms s tnum 80;den s^412*s^341*s^282*s80;Fs num/denres solve(den) %求解分母多项式等于 0 的根&#xff08;即特征根&#xff09;Ft simplify(ilaplace(Fs, s, t)) % %对 F(s)做拉普拉斯逆变换&#xff0c;将变量从拉普拉斯域…

(8-1)自动驾驶中的无地图环境路径探索:D* Lite算法简介

在自动驾驶领域&#xff0c;无地图环境下的路径探索是极具挑战性的课题。本章聚焦于 D* Lite 算法&#xff0c;这是一种在未知或部分已知环境中进行高效路径规划的先进算法。我们将从 D* Lite 算法的应用领域、核心思想、实现步骤入手&#xff0c;通过实战案例深入剖析其在迷宫…

Unity AI Navigation 从 0 到 1:一篇吃透新 NavMesh 系统的实战

一、为什么你必须升级到老 NavMesh&#xff1f; 如果你还在用 2021 LTS 之前的 Navigation 窗口做 Bake&#xff0c;那你一定踩过这些坑&#xff1a; 场景里一移动箱子&#xff0c;就要重烤 NavMesh&#xff0c;CPU 直接爆炸&#xff1b; 不同体型的 NPC 必须共用同一张 Mesh…

电-气-热综合能源系统耦合优化调度Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

(8-2-01)自动驾驶中的无地图环境路径探索:基于Pygame的交互式路径规划器(1)

8.2 实战案例&#xff1a;基于Pygame的交互式路径规划器本项目是一个基于 Pygame 的交互式路径规划器&#xff0c;通过 A* 和 D* Lite 算法实现路径规划。用户可以在 GUI 界面中设置起点、终点和障碍物&#xff0c;并观察路径规划的过程和结果&#xff0c;以及实时更新的路径信…

Unity3D AI Navigation 详解:从基础概念到实战应用

引言在 Unity 游戏开发中&#xff0c;实现智能的 AI 角色移动是提升游戏体验的关键。Unity 提供的 AI Navigation 系统&#xff0c;能够帮助开发者轻松创建能够自主寻路、规避障碍、跨越特殊地形的角色。无论你是初学者还是有经验的开发者&#xff0c;掌握这套系统都能让你在游…

计及多能耦合的区域综合能源系统电气热能流计算Matlab实现

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

Unity 的AI Navigation 系统详细总结

Unity 的AI Navigation 系统&#xff08;2022.2 及以上版本通过 AI Navigation 包实现&#xff09;可让角色在游戏世界智能导航&#xff0c;核心基于自动生成的导航网格&#xff08;NavMesh&#xff09; &#xff0c;支持动态障碍物实时调整导航、OffMesh Link实现跳跃 / 开门等…

Unity3D AI Navigation 完全指南:从基础到实战,让角色智能导航

在 Unity 开发中&#xff0c;让游戏角色自主避开障碍、找到最优路径&#xff0c;是提升玩法体验的关键。Unity 的 AI Navigation 系统&#xff08;2022.2 版本已整合为 AI Navigation 包&#xff09;通过导航网格&#xff08;NavMesh&#xff09;、智能 Agent 和动态障碍物机制…

Unity3D AI导航系统完全指南:从核心概念到动画耦合

在游戏开发中&#xff0c;让角色智能地在场景中移动是提升沉浸感的关键。Unity的AI Navigation包通过导航网格&#xff08;NavMesh&#xff09;和寻路系统&#xff0c;让开发者轻松实现角色的自主导航。本文将基于官方文档&#xff0c;带你全面了解AI导航的核心概念、新功能、实…

RabbitMQ在大数据风控系统中的应用案例

RabbitMQ在大数据风控系统中的应用案例 关键词:RabbitMQ、大数据风控、消息队列、实时计算、分布式系统 摘要:在金融科技(FinTech)领域,大数据风控系统如同"数字安全卫士",需要724小时实时监控用户行为、交易数据,快速识别欺诈风险。本文将以"快递中转站…

CRM服务质量差?提示工程架构师的3个Prompt解决方案

CRM服务质量差&#xff1f;提示工程架构师的3个Prompt解决方案 一、引言&#xff1a;为什么你的CRM总是“答非所问”&#xff1f; 1. 一个让客户崩溃的真实场景 上周&#xff0c;我朋友小琳遇到了一件糟心的事&#xff1a;她在某美妆品牌官网买了一瓶精华&#xff0c;快递延迟了…