设计模式(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)。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值