设计模式学习(九) 组合模式 Composite

1.组合模式的定义以及类图

组合模式通俗点来讲,就是数据结构中的树结构。其适用于单个对象和组合对象的使用具有一致性时(最典型的就是目录结构),将对象组合合成树形结构,以表示“部分-整体”。
具体的构造,根据其类图可以很容易看出来,其类图如下:
组合模式类图
根据类图可知,组合模式主体为一个抽象基类,其派生类为叶节点对象和枝节点对象,其中叶节点就是标准的末端节点,其没有对应的子节点,所以只继承相关的功能函数Operarion。而枝节点是可以作为原抽象基类的整体的,所以其派生了所有的虚函数,使其可以增加或删除(add、remove)节点,并读取其下层的子节点(getChild),当然,其仍然会继承相关的功能函数Operation。这就是组合模式中的两种实例化对象的具体区别,通过根节点不断向下延伸,而末端节点必均为叶节点,而其中的分支节点都为枝节点。

2.组合模式的代码实现

这里采用了文件夹形式的构造,其抽象基类为AbFile,叶节点为File,枝节点为Folder。实例化的对象中包含了两种图片(jpg)和两种文本文件(txt),各自代表篮球中的詹姆斯和足球中的梅西。其中还增加一个输入根节点显示其属下所有节点的函数ShowAllFile,这是模仿树结构的形式实现的。
具体代码如下:

#include <iostream>
#include <string>
#include <list>
using namespace std;

class AbFile
{
public:
	virtual void display() = 0;
	virtual int add(AbFile* abfile) = 0;
	virtual int remove(AbFile* abfile) = 0;
	virtual list<AbFile*>* getChild() = 0;
};

class File : public AbFile
{
public:
	File(string name, string type) : m_name(name), m_type(type) {}
	void display() override
	{
		cout << "File is " << m_name << m_type << endl;
	}
	int add(AbFile* abfile) override { return -1; }
	int remove(AbFile* abfile) override { return -1; }
	list<AbFile*>* getChild() override { return NULL; }
private:
	string m_name;
	string m_type;
};

class Folder : public AbFile
{
public:
	Folder(string name)
	{
		m_name = name;
		m_child = new list<AbFile*>;
		m_child->clear();
	}
	void display()
	{
		cout << "Folder name is " << m_name << endl;
	}
	int add(AbFile* abfile)
	{
		m_child->push_back(abfile);
		return 1;
	}
	int remove(AbFile* abfile)
	{
		m_child->remove(abfile);
		return 1;
	}
	list<AbFile*>* getChild()
	{
		return m_child;
	}
private:
	string m_name;
	list<AbFile*>* m_child;
};

void ShowAllFile(AbFile* abfile)
{
	if (abfile == NULL)
	{
		return;
	}
	list<AbFile*>* templist = abfile->getChild();
	if (templist != NULL)
	{
		cout << " ";
		abfile->display();
		for (auto &s : *templist)
		{
			ShowAllFile(s);
		}
	}
	else
	{
		abfile->display();
	}
}

int main()
{
	File* image1 = new File("foteball", ".jpg");
	File* image2 = new File("basketball", ".jpg");
	File* text1 = new File("Messi", ".txt");
	File* text2 = new File("James", ".txt");
	Folder* Person = new Folder("Person");
	Folder* Person1 = new Folder("Person1");
	Folder* Person2 = new Folder("Person2");

	Person->add(Person1);
	Person->add(Person2);
	Person1->add(image1);
	Person1->add(text1);
	Person2->add(image2);
	Person2->add(text2);

	cout << "*****Person's Place*****" << endl;
	ShowAllFile(Person);
	cout << "*****Person1's Place*****" << endl;
	ShowAllFile(Person1);
	cout << "*****Person2's Place*****" << endl;
	ShowAllFile(Person2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值