设计模式(3)--对象结构(3)--组合

1. 意图

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

2. 三种角色

    抽象组件(Component)、组合式节点(Composite)、叶节点(Leaf)

3. 优点

   3.1 定义了包含基本对象和组合对象的类层次结构。

         客户代码中,用到基本对象的地方都可以使用组合对象。

   3.2 简化客户代码,不需要关心是叶节点还是组合。

   3.3 使得更容易增加新类型的组件

   3.4 使设计变得更加一般化

4. 缺点

    4.1 只能在运行时刻进行类型检查

5. 相关模式

    5.1 通常“部件-父部件”连接用于Responsibility of Chain模式

    5.2 装饰模式经常与Composite模式一起使用,通常有个公共的父类。

    5.3 Flyweight让你共享组件,但不能引用它们的父部件。

    5.4 Iterator可用来遍历Composite

    5.5 Visitor将本来应该分布在Composite和Leaf类中的操作和行为局部化。

6. 代码示意(C++)
#pragma once
#include <iostream>
#include <string>
#include <vector>
using namespace std;class Component
{
protected:string m_strName;
public:	Component(const string &strName){m_strName = strName;}virtual void Operation(int depth) = 0;virtual bool Add(Component* pComponent) = 0;virtual bool Remove(Component* pComponent) = 0;virtual Component* GetChild(int pos) = 0;
public:string GetName() { return m_strName; }
protected:string GetPreLine(int depth){string preLine = "";for (int i = 0; i < depth; ++i){preLine += "--";}return preLine;}
};class Leaf : public Component
{
public:Leaf(const string& strName) :Component(strName){}virtual bool Add(Component* pComponent) {cout << "Leaf can't add" << endl;return false;}virtual bool Remove(Component* pComponent) {cout << "Leaf can't remove" << endl;return false;}virtual Component* GetChild(int pos) {cout << "Leaf has no child" << endl;return 0;}virtual void Operation(int depth) {cout << GetPreLine(depth) << m_strName << endl;}
};class Composite :public Component
{
private:vector<Component*> m_vecChildren;
public:Composite(const string& strName) :Component(strName) {m_strName = strName;}~Composite(){auto it = m_vecChildren.begin();while (it != m_vecChildren.end()) {delete* it;it++;}m_vecChildren.clear();}virtual bool Add(Component* pComponent) {if (pComponent == 0) {return false;}m_vecChildren.emplace_back(pComponent);//cout << "children size:" <<m_vecChildren.size()<< endl;return true;}virtual bool Remove(Component* pComponent) {if (pComponent == 0) {return false;}m_vecChildren.erase(std::remove_if(m_vecChildren.begin(), m_vecChildren.end(), [&](Component *p) { return p->GetName().compare(pComponent->GetName()) == 0; }), m_vecChildren.end());//cout << "children size:" << m_vecChildren.size() << endl;//cout << "children capacity:" << m_vecChildren.capacity() << endl;return true;}virtual Component* GetChild(int pos) {if (pos >= 0 && pos < m_vecChildren.size()) {return m_vecChildren[pos];}return 0;}virtual void Operation(int depth) {cout << GetPreLine(depth) << m_strName << endl;auto it = m_vecChildren.begin();while (it != m_vecChildren.end()) {(*it)->Operation(depth+1);it++;}}
};
#include "Component.h"
int main() {Composite* pRoot= new Composite("Root");pRoot->Add(new Leaf("Leaf1"));pRoot->Add(new Leaf("Leaf2"));Composite* pComposite = new Composite("Composite");pComposite->Add(new Leaf("Leaf3"));pRoot->Add(pComposite);pRoot->Operation(0);cout << "------------------" << endl;pRoot->Remove(pComposite);pRoot->Operation(0);delete pComposite;delete pRoot;
}

运行结果:

6.1 组合Composite是一种基本对象Component(3.1)。

6.2 Leaf也是一种基本对象,只需要关注Component接口(3.2)。

6.2 继承Component接口,就可以增加新类型的组件(3.3)。

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

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

相关文章

C++相关闲碎记录(14)

1、数值算法 &#xff08;1&#xff09;运算后产生结果accumulate() #include "algostuff.hpp"using namespace std;int main() {vector<int> coll;INSERT_ELEMENTS(coll, 1, 9);PRINT_ELEMENTS(coll);cout << "sum: " << accumulate(…

Spring入门

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

鸿蒙ArkTS Web组件加载空白的问题原因及解决方案

问题症状 初学鸿蒙开发&#xff0c;按照官方文档Web组件文档《使用Web组件加载页面》示例中的代码照抄运行后显示空白&#xff0c;纠结之余多方搜索后扔无解决方法。 运行代码 import web_webview from ohos.web.webviewEntry Component struct Index {controller: web_webv…

docker入门小结

docker是什么&#xff1f;它有什么优势&#xff1f; 快速获取开箱即用的程序 docker使得所有的应用传输就像我们日常通过聊天工具文件传输一样&#xff0c;发送方将程序传输到超级码头而接收方也只需通过超级码头进行获取即可&#xff0c;就像一只鲸鱼拖着货物来回运输一样。…

使用java获取nvidia显卡信息

前言 AI开发通常使用到GPU&#xff0c;但通常使用的是python、c等语言&#xff0c;java用的则非常少。这也导致了java在gpu相关的库比较少。现在的需求是要获取nvidia显卡的使用情况&#xff0c;如剩余显存。这里给出两种较简单的解决方案。 基于nivdia-smi工具 显卡是硬件&a…

AMD 自适应和嵌入式产品技术日

概要 时间&#xff1a;2023年11月28日 地点&#xff1a;北京朝阳新云南皇冠假日酒店 主题内容&#xff1a;AMD自适应和嵌入式产品的更新&#xff0c;跨越 云、边、端的AI解决方案&#xff0c;赋能智能制造的机器视觉与机器人等热门话题。 注&#xff1a;本文重点关注FPGA&a…

【51单片机系列】直流电机使用

本文是关于直流电机使用的相关介绍。 文章目录 一、直流电机介绍二、ULN2003芯片介绍三、在proteus中仿真实现对电机的驱动 51单片机的应用中&#xff0c;电机控制方面的应用也很多。在学习直流电机(PWM)之前&#xff0c;先使用GPIO控制电机的正反转和停止。但不能直接使用GPIO…

textarea 网页文本框在光标处添加内容

在前端研发中我们经常需要使用脚本在文本框中插入内容。如果产品要求不能直接插入开始或者尾部&#xff0c;而是要插入到光标位置&#xff0c;此时我们就需要获取光标/光标选中的位置。 很多时候&#xff0c;我在格式化文本处需要选择选项&#xff0c;将选择的信息输入到光标位…

关于“Python”的核心知识点整理大全25

目录 10.3.4 else 代码块、 10.3.5 处理 FileNotFoundError 异常 alice.py 在这个示例中&#xff0c;try代码块引发FileNotFoundError异常&#xff0c;因此Python找出与该错误匹配的 except代码块&#xff0c;并运行其中的代码。最终的结果是显示一条友好的错误消息&#x…

基于循环神经网络长短时记忆(RNN-LSTM)的大豆土壤水分预测模型的建立

Development of a Soil Moisture Prediction Model Based on Recurrent Neural Network Long Short-Term Memory in Soybean Cultivation 1、介绍2、方法2.1 数据获取2.2.用于预测土壤湿度的 LSTM 模型2.3.土壤水分预测的RNN-LSTM模型的建立条件2.4.预测土壤水分的RNN-LSTM模型…

【ArkTS】Watch装饰器

Watch装饰器&#xff0c;相当于Vue中的监听器 以及 React中使用useEffect监听变量 使用Watch装饰器&#xff0c;可以监听一个数据的变化&#xff0c;并进行后续的响应。 使用方法&#xff1a; Watch(‘回调函数’)&#xff0c;写在State装饰器后&#xff08;其实写在前面也行&a…

LabVIEW开发地铁运行安全监控系统

LabVIEW开发地铁运行安全监控系统 最近昌平线发生的故障事件引起了广泛关注&#xff0c;暴露了现有地铁运行监控系统在应对突发情况方面的不足。为了提高地铁系统的运行安全性&#xff0c;并防止类似事件再次发生&#xff0c;提出了一套全面的地铁运行安全监控系统方案。此方案…

[Verilog] Verilog 基本格式和语法

主页&#xff1a; 元存储博客 全文 3000 字 文章目录 1. 声明格式1.1 模块声明1.2 输入输出声明1.3 内部信号声明1.4 内部逻辑声明1.5 连接声明1.6 数据类型声明1.7 运算符和表达式1.8 控制结构 2. 书写格式2.1 大小写2.2 换行2.3 语句结束符2.4 注释2.5 标识符2.6 关键字 1. 声…

python/c++ Leetcode题解——746. 使用最小花费爬楼梯

目录 方法一&#xff1a;动态规划 复杂度分析 方法一&#xff1a;动态规划 假设数组 cost 的长度为 n&#xff0c;则 n 个阶梯分别对应下标 0 到 n−1&#xff0c;楼层顶部对应下标 n&#xff0c;问题等价于计算达到下标 n 的最小花费。可以通过动态规划求解。 创建长度为 n…

【面试】测试/测开(NIG2)

145. linux打印前row行日志 参考&#xff1a;linux日志打印 前10行日志 head -n 10 xx.log后10行日志 tail -n 10 xx.log tail -10f xx.log使用sed命令 sed -n 9,10p xx.log #打印第9、10行使用awk命令 awk NR10 xx.log #打印第10行 awk NR>7 && NR<10 xx.log …

爬虫 selenium语法 (八)

目录 一、为什么使用selenium 二、selenium语法——元素定位 1.根据 id 找到对象 2.根据标签属性的属性值找到对象 3.根据Xpath语句获取对象 4.根据标签名获取对象 5.使用bs语法获取对象 6.通过链接文本获取对象 三、selenium语法——访问元素信息 1.获取属性的属性值…

MySQL 常用数据类型总结

面试&#xff1a; 为什么建表时,加not null default ‘’ / default 0 答:不想让表中出现null值. 为什么不想要的null的值 答:&#xff08;1&#xff09;不好比较,null是一种类型,比较时,只能用专门的is null 和 is not null来比较. 碰到运算符,一律返回null &#xff08…

ES-模糊查询

模糊查询 1 wildcard 准备数据 POST demolike/_bulk {"index": {"_id": "1"} } {"text": "草莓熊是个大坏蛋" } {"index": {"_id": "2"} } {"text": "wolf 也是一个坏蛋&q…

C# WPF上位机开发(树形控件在地图软件中的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们聊过图形软件的开发方法。实际上&#xff0c;对于绘制的图形&#xff0c;我们一般还会用树形控件管理一下。举个例子&#xff0c;一个地图…

云原生之深入解析使用Telepresence轻松在本地调试和开发Kubernetes应用程序

一、 准备 telepresence 下载&#xff1a;https://www.telepresence.io/docs/latest/install/kubectl 下载&#xff1a;https://kubernetes.io/docs/tasks/tools/ 二、版本检测 $telepresence version Client: v2.5.3 (api v3) Root Daemon: not running User Daemon: not r…