C++之组合(Composite)模式

举报
Hermit_Rabbit 发表于 2022/10/21 22:30:10 2022/10/21
【摘要】 0. 简介这一次我们继续来讲结构型模式中的组合设计模式。组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。在一般组合模式中中声明所有用来管理子对象的方法,其中包括Add、Remove等,这样实现组合方法接口的所有子类都具备了Add和Remove,但是只是是虚函数,并不会去使用。 1. 组合模式结构如下图所示为组合模式的示意图,主要的核心部...

0. 简介

这一次我们继续来讲结构型模式中的组合设计模式。组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。
在一般组合模式中中声明所有用来管理子对象的方法,其中包括Add、Remove等,这样实现组合方法接口的所有子类都具备了Add和Remove,但是只是是虚函数,并不会去使用。

1. 组合模式结构

如下图所示为组合模式的示意图,主要的核心部分为容器部分(Composite),它是含有子组件的类.
在这里插入图片描述

  1. 组件(Component):为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component的子组件。
    1). Component::ComponentPtr:定义了各个组件共有的行为接口,由各个组件的具体实现.
    2). Component::add添加一个子组件
    3). Component::remove::删除一个子组件.
    4). Component::display:获得子组件的指针.

  2. 容器(Composite):是含有子组件的类,其内部包含了多种方法,主要是在当中实现了add与remove这类的操作用于对子组件进行控制。

  3. 叶节点(Leaf):是叶子结点,也就是不含有子组件的结点。

2. 组合模式示例

组合模式的操作代表着其可以很多种相似的操作,并在调用时可以统一的调用出来。组合模式的核心思想就是:一个组织有很多子组织,而无论子组织是单独一个部门或是一个分组织。该组织都希望把它们当成一样的子组织来管理。对于分组织,只用通知分组织就可以了,而不用一一通知分组织的各个部门。

// CompositeModel.h文件
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

class ComponentPtr
{
protected:
	std::string m_strName;
public:
	ComponentPtr(std::string str)
	{
		m_strName = str;
	}
	virtual void add(ComponentPtr * p) = 0;
	virtual void remove(ComponentPtr * p) = 0;
	virtual void display() = 0;
};

class LeafPtr : public ComponentPtr
{
public:
	LeafPtr(std::string str) : ComponentPtr(str) {}
	void add(ComponentPtr * p)
	{
		std::cout << "Leaf cannot add" << std::endl;
	}
	void remove(ComponentPtr * p)
	{
		std::cout << "Leaf cannot remove" << std::endl;
	}
	void display()
	{
		std::cout << m_strName << std::endl;
	}
};

class CompositePtr : public ComponentPtr
{
private:
	// 这里使用智能指针不用自己释放new的内存
	std::vector<std::shared_ptr<ComponentPtr>> m_vec;
public:
	CompositePtr(std::string str) : ComponentPtr(str) {};
	~CompositePtr()
	{
		if (!m_vec.empty())
		{
			m_vec.clear();
		}
	}
	void add(ComponentPtr * p)
	{
		auto it = find_if(m_vec.begin(), m_vec.end(), 
			[p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
		if (it == m_vec.end())
			m_vec.push_back(std::shared_ptr<ComponentPtr>(p));
	}
	void remove(ComponentPtr * p)
	{
		auto it = find_if(m_vec.begin(), m_vec.end(),
			[p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
		if (it == m_vec.end())
			return;
		m_vec.erase(it);
	}
	void display()
	{
		for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
		{
			(*it)->display();
		}
	}
};


/**#include <iostream>
#include "CompositeModel.h"

int main()
{
	using namespace std;
	// 组合模式
	CompositePtr * p = new CompositePtr("总部");
	p->add(new LeafPtr("总部财务部门"));
	p->add(new LeafPtr("总部人力资源部门"));
	CompositePtr * p1 = new CompositePtr("上海分部");
	p1->add(new LeafPtr("上海分部财务部门"));
	p1->add(new LeafPtr("上海分部人力资源部门"));
	p->add(p1);
	p->display();
	getchar()
	return 0;
}**/

…详情请参照古月居

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。