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

2023-12-17 16:40:26
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)。

文章来源:https://blog.csdn.net/myepicure/article/details/134908955
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。