设计模式12-组合模式

本文介绍了组合模式,一种用于构建部分-整体层次结构的软件设计模式。通过抽象构件、叶子构件和容器构件的定义,展示了如何在C++中实现文件和文件夹的树形结构。代码示例演示了如何创建、添加和显示文件系统中的文件和文件夹,以及如何遍历和展示整个结构。

一、什么是组合模式

组合多个对象形成树形结构以表示“部分-整体”的结构层次。组合模式对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性。可以简单理解为一组对象集合。其应用场景的特殊性,数据必须能表示成树形结构

树形结构在软件中随处可见,例如操作系统中的目录结构、应用软件中的菜单、办公系统中的公司组织结构等等,这样的组织形式的特点在于:叶子节点不再包含成员对象,而容器节点可以包含成员对象,这些对象可以是叶子节点,也可以是容器节点。

下面是UML类图
在这里插入图片描述
在这里插入图片描述
用来表达和处理树形结构的数据。
在这里插入图片描述
在这里插入图片描述

二、模式结构

Component(抽象构件):可以是接口或抽象类,定义了构件的一些公共接口,这些接口是管理或者访问它的子构件的方法(如果有子构件),具体的实现在叶子构件和容器构件中进行。
Leaf(叶子构件):它代表树形结构中的叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法(非叶子构件功能,属于容器构件的功能),可以通过抛出异常、提示错误等方式进行处理。
Composite(容器构件) :表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为。

三、代码实现

模拟对文件和文件夹的显示

Component(抽象构件): AbstractFile

Leaf(叶子构件):ImageFile TextFile 

Composite(容器构件):Folder
#include<iostream>
#include <list>
using namespace std;


/// Component(抽象构件): AbstractFile
class AbstractFile {
public:
	virtual ~AbstractFile() = default;
	virtual void add(AbstractFile *file) = 0;
	virtual void remove(AbstractFile *file) = 0;
	virtual void display() = 0;
	
protected:
	AbstractFile() = default;
};

/// Leaf(叶子构件): ImageFile  TextFile 
class ImageFile :public AbstractFile
{


private:
	string name;
public:
	ImageFile(string str) :name(str)
	{

	}
	void add(AbstractFile *file)
	{
		cout << "不支持\n";
		return;
	}

	void remove(AbstractFile *file)
	{
		cout << "不支持\n";
		return;
	}

	void display()
	{
		cout <<"图像文件:"<< name.c_str() << endl;
		return;
	}
	

};


class TextFile :public AbstractFile
{

private:
	string name;
public:
	TextFile(string str) :name(str)
	{

	}
	void add(AbstractFile *file)
	{
		cout << "不支持\n";
		return;
	}

	void remove(AbstractFile *file)
	{
		cout << "不支持\n";
		return;
	}

	void display()
	{
		cout << "文本文件:" << name.c_str() << endl;
		return;
	}


};

/// Composite(容器构件): Folder
class Folder :public AbstractFile
{
private:
	string name;
	list<AbstractFile *> m_list;
public:
	Folder(string str) :name(str)
	{

	}
	void add(AbstractFile *file)
	{
		m_list.push_back(file);
	}

	void remove(AbstractFile *file)
	{
		m_list.remove(file);
	}

	void display()
	{
		cout << "------文件夹:" << name.c_str() <<"--------" <<endl;
		for (auto it :m_list)
		{
			it->display();
		}
	}

};

void main()
{
	//针对抽象构件编程
	AbstractFile *file1, *file2, *file3, *file4, *folder1, *folder2, *folder3, *folder0;

	folder0 = new Folder("根目录文件夹");

	folder1 = new Folder("图像文件夹");
	folder2 = new Folder("文本文件夹");

	folder3 = new Folder("视频文件夹");

	file1 = new ImageFile("图片01.jpg");
	file2 = new ImageFile("图片02.gif");

	file3 = new TextFile("文本01.txt");
	file4 = new TextFile("文本02.doc");
	

	folder1->add(file1);
	folder1->add(file2);

	folder2->add(file3);
	folder2->add(file4);
	

	folder0->add(folder1);
	folder0->add(folder2);
	folder0->add(folder3);

	//从 根目录文件夹 节点开始进行模拟杀毒操作
	folder0->display();


	delete file1;
	delete file2;
	delete file3;
	delete file4;
	
	delete folder0;
	delete folder1;
	delete folder2;
	delete folder3;
	

	system("pause");
}

结果:
在这里插入图片描述
案例二:

#include <iostream>
#include <string>
#include <list>
using namespace std;
class AbstractFile
{
public:
	virtual void add(AbstractFile *pFile) = 0;
	virtual void remove(AbstractFile *pFile) = 0;
	virtual void display() = 0
	{
		cout << m_strName << endl;;
	}
	AbstractFile(string name) :m_strName(name){}
	virtual ~AbstractFile(){}
private: 
	string m_strName;
};

class TextFile :public AbstractFile
{
public:
	void add(AbstractFile *pFile)
	{

	}
	void remove(AbstractFile *pFile)
	{

	}
	void display()
	{
		cout << "  - ";
		AbstractFile::display();
	}

	TextFile(string strName) :AbstractFile(strName)
	{

	}
};

class ImageFile :public AbstractFile
{
public:
	void add(AbstractFile *pFile)
	{

	}
	void remove(AbstractFile *pFile)
	{

	}
	void display()
	{
		cout << "  - ";
		AbstractFile::display();
	}

	ImageFile(string strName) :AbstractFile(strName)
	{

	}
};

class Folder :public AbstractFile
{
public:
	void add(AbstractFile *pFile)
	{
		m_list.push_back(pFile);
	}
	void remove(AbstractFile *pFile)
	{
		m_list.remove(pFile);
	}
	void display()
	{
		cout << "+ ";
		AbstractFile::display();

		for (auto node :m_list)
		{
			node->display();
		}
	}

	Folder(string strName) :AbstractFile(strName)
	{

	}
private:
	list<AbstractFile*>m_list;

};
void main()
{
	TextFile *pTxt = new TextFile("1.txt");
	ImageFile *pImg = new ImageFile("1.jpg");
	Folder *pDir1 = new Folder("私密文件夹");
	pDir1->add(pTxt);
	pDir1->add(pImg);
	

	TextFile *pTxt1 = new TextFile("2.txt");
	ImageFile *pImg1 = new ImageFile("2.jpg");

	Folder *pDir2 = new Folder("种子文件夹");
	pDir2->add(pTxt1);
	pDir2->add(pImg1);

	Folder *pRoot = new Folder("不能看");

	pRoot->add(pDir1);
	pRoot->add(pDir2);
	pRoot->display();

	//懒得释放。。。

	system("pause");
}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

发如雪-ty

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

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

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

打赏作者

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

抵扣说明:

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

余额充值