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

news2024/10/5 14:14:54
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.coloradmin.cn/o/1317567.html

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

相关文章

八大排序——快速排序(霍尔 | 挖空 | 前后指针 | 非递归)

我们今天来讲讲八大排序中的快速排序&#xff0c;快速排序最明显的特点就是排序快&#xff0c;时间复杂度是O&#xff08;N* logN&#xff09;&#xff0c;但是坏处就是如果排序的是一个逆序的数组的时候&#xff0c;时间复杂度是O&#xff08;N^2&#xff09;,还不用我们的插入…

【Hive_03】单行函数、聚合函数、窗口函数、自定义函数、炸裂函数

1、函数简介2、单行函数2.1 算术运算函数2.2 数值函数2.3 字符串函数&#xff08;1&#xff09;substring 截取字符串&#xff08;2&#xff09;replace 替换&#xff08;3&#xff09;regexp_replace 正则替换&#xff08;4&#xff09;regexp 正则匹配&#xff08;5&#xff…

操作系统期末复习-内存管理

一、内存管理 分页存储管理&#xff0c;是将一个进程的逻辑地址空间分成若干个大小相等的片&#xff0c;称为页面或页&#xff0c;并为各页加以编号&#xff0c;从0开始&#xff0c;如第0页、第1页等。相应地&#xff0c;也把内存空间分成与页面相同大小的若干个存储块&#xf…

直线追踪

由于项目的需要&#xff0c;最近在做一个直线追踪的东西&#xff0c;但是网上的代码关于车道线或者别的什么之类的直线追踪的代码只是提了一下&#xff0c;相关的代码并不是公开的&#xff0c;所以自己写了一些直线追踪的代码。 代码使用的是kalman滤波进行直线追踪&#xff0…

完美解决labelimg xml转可视化中文乱码问题,不用matplotlib

背景简述 我们有一批标注项目要转可视化&#xff0c;因为之前没有做过&#xff0c;然后网上随意找了一段代码测试完美&#xff08;并没有&#xff09;搞定&#xff0c;开始疯狂标注&#xff0c;当真正要转的时候傻眼了&#xff0c;因为测试的时候用的是英文标签&#xff0c;实…

Sci. Rep. | 一个对任意分子体系实现准确且高效几何深度学习的通用框架

这篇工作是来自纽约城市大学/康奈尔医学院谢磊团队的一篇论文。作者提出了一个通用框架&#xff0c;PAMNet&#xff0c;可以对任意分子体系实现准确且高效的几何深度学习。在小分子性质、RNA三维结构以及蛋白质-配体结合亲和力的预测任务上&#xff0c;PAMNet在准确性和效率方面…

网络编程-认识套接字socket

文章目录 套接字概念端口号网络字节序 套接字类型流套接字数据报套接字 socket常见APIsocket函数bind函数listen函数accept函数connect函数sockaddr结构 套接字概念 socket套接字是进程之间一种通信机制&#xff0c;通过套接字可以在不同进程之间进行数据交流。在TCP/UDP中&…

将html的radio单选框自定义样式为正方形和对号

将html的radio单选框自定义样式为正方形和对号 背景&#xff1a; 如何能把html的<input type"radio" name"option">改成自定义的样式呢&#xff1f;比如想要把他变成正方形&#xff0c;选中的时候是对号。默认的样式太丑了 默认样式&#xff1a; 自…

[数学]三角形的五心之内心

三角形内心的性质 三角形内切圆的圆心称为三角形的内心。内心也是三角形三个角的角平分线的交点 性质1 1.1 设 I I I为 △ A B C △ABC △ABC内一点&#xff0c;则 I I I为 △ A B C △ABC △ABC内心的充要条件是下列条件之一&#xff1a; 1.1.1 I I I到 △ A B C △ABC △…

【C语言】RDMACM、Verbs API与epoll一起使用的示例

一、epoll介绍 epoll是Linux内核为处理大批量文件描述符而作了改进的poll&#xff0c;是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。 以下是epoll的主要使用方法和优点&#xff1a; epo…

代码随想录刷题题Day15

刷题的第十五天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day15 任务 ● 513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历…

整理了上百个开源中文大语言模型,涵盖模型、应用、数据集、微调、部署、评测

自ChatGPT为代表的大语言模型&#xff08;Large Language Model, LLM&#xff09;出现以后&#xff0c;由于其惊人的类通用人工智能&#xff08;AGI&#xff09;的能力&#xff0c;掀起了新一轮自然语言处理领域的研究和应用的浪潮。 尤其是以ChatGLM、LLaMA等平民玩家都能跑起…

广州华锐互动:汽车电子线束加工VR仿真培训与实际生产场景相结合,提高培训效果

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为企业和个人带来了前所未有的便利。在汽车制造行业中&#xff0c;线束加工作为一项关键的生产工艺&#xff0c;其质量直接影响到汽车的性能和安全。因此&#xff0c;…

LCR 181. 字符串中的单词反转

解题思路&#xff1a; class Solution {public String reverseMessage(String message) {message message.trim(); // 删除首尾空格int j message.length() - 1, i j;StringBuilder res new StringBuilder();while (i > 0) {while (i >…

局域网环境下的ntp对时

服务端&#xff1a; 此处为v4-sp4服务器 安装ntp&#xff0c;apt-get install ntp -y ,若为离线环境&#xff0c;则安装ntp和libopts25两个包。 配置&#xff1a; 在/etc/ntp.conf的配置文件里 加入 restrict default nomodify notrap noquery restrict 127.0.0.1 rest…

时序预测 | Python实现GRU-XGBoost组合模型电力需求预测

时序预测 | Python实现GRU-XGBoost组合模型电力需求预测 目录 时序预测 | Python实现GRU-XGBoost组合模型电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前…

【IDEA】关于快捷键行注释时会从行首开始注释

前言 每次在使用IDEA写代码时&#xff0c;用快捷键进行行注释的时候&#xff0c;//会处于行首位置 但是我们想要的是这种注释效果 修改 IDEA中打开settings 找到Editor - Code Style- Java - 找到Code Genneration&#xff0c;取消勾选Line comment at first column&#x…

如何批量获取CSDN文章数据并进行持久化

自己去看文章数据的话&#xff0c;比较慢&#xff0c;所以一直想通过程序来批量获取CSDN的文章数据&#xff0c;最近研究了一下&#xff0c;发现还是挺简单的&#xff0c;能够直接通过解析json来获取文章数据&#xff0c;跟大家分享一下。 文章目录 一、步骤1、首先我们到自己的…

VUE学习三、前端项目部署

1.前端项目打包 执行命令 npm run build:prod正常命令结束 , 会在前端项目里面出现dist文件夹 2.nginx下载安装 nginx下载 : http://nginx.org/en/download.html Windows 下载版本 Mainline version&#xff1a;Mainline 是 Nginx 目前主力在做的版本&#xff0c;可以说…