C++ 设计模式之组合模式

C++ 设计模式之组合模式

简介

1、组合模式(Composite)是一种将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。在组合模式中,客户端将一组对象当作一个单一的对象来处理,而无需关心这组对象到底是由一个单独的对象组成,还是由一组对象(即对象的组合)组成。

2、组合模式 (Composite)应用场景包括但不限于:

2.1、当你想表示对象的部分-整体层次结构时。

2.2、当你希望用户可以忽略组合对象与单个对象的差异时。

2.3、当你希望使用多态集合以统一方式处理所有对象时。

3、组合模式 (Composite)的构成

3.1、Component(抽象构件):定义参加组合对象的共有方法和接口,实现所有类共有的默认行为,声明一个接口用于访问和管理Component的子对象。

c 复制代码
class FileSystemComponent
{
public:
	virtual void print(const std::string& indent) const = 0;
	virtual ~FileSystemComponent() {};
};

3.2、Leaf(叶节点):是组合中的对象,它没有子节点,实现了在Component中声明的方法,包括与业务逻辑相关的操作,或者是一个原子操作,在组合中表示叶子节点对象,叶子节点没有子节点。

c 复制代码
class File : public FileSystemComponent
{
public:
	File(const std::string& name);
	void print(const std::string& indent) const;
private:
	std::string name;
};

3.3、Composite(复合节点):是组合中对象的另一类,它可以包含子节点,其子节点可以是叶子节点,也可以是复合节点,它提供一个集合来存储子节点,实现Component中声明的接口,特别是用于添加、删除、以及获取子节点的操作。

c 复制代码
class Directory : public FileSystemComponent
{
public:
	Directory(const std::string& name);
	void print(const std::string& indent) const;
	void addComponent(const std::shared_ptr<FileSystemComponent>& component);
private:
	std::string name;
	std::vector<std::shared_ptr<FileSystemComponent>> children;
};

4、组合模式 (Composite)的优点

4.1、清晰的层次结构:组合模式定义了包含基本对象和复合对象的类层次结构,这使得构建对象的层次结构变得简单易懂。

4.2、易于扩展:新的组件类加入非常方便,无需改变现有代码,符合开闭原则。

4.3、客户端透明性:客户端可以统一对待单个对象和组合对象,简化了客户端代码。

4.4、复用性:可以通过组合小的组件来构造复杂的对象,提高了系统的灵活性和复用性。

5、组合模式 (Composite)的缺点

5.1、设计变得更加抽象:如果设计过于通用,可能会导致系统中出现许多小类,使设计过度泛化。

5.2、难以限制组合中的组件:在组合模式中很难对组件的类型进行限制,可能会导致将某些不应该加入的对象加入到组合中。

简单示例

1、定义

c 复制代码
// 组件接口
class FileSystemComponent
{
public:
	virtual void print(const std::string& indent) const = 0;
	virtual ~FileSystemComponent() {};
};

// 叶子组件:文件
class File : public FileSystemComponent
{
public:
	File(const std::string& name);
	void print(const std::string& indent) const;
private:
	std::string name;
};

// 复合组件:文件夹
class Directory : public FileSystemComponent
{
public:
	Directory(const std::string& name);
	void print(const std::string& indent) const;
	void addComponent(const std::shared_ptr<FileSystemComponent>& component);
private:
	std::string name;
	std::vector<std::shared_ptr<FileSystemComponent>> children;
};

2、实现

c 复制代码
File::File(const std::string& name) : name(name)
{

}

void File::print(const std::string& indent) const
{
	std::cout << indent << name << std::endl;
}

Directory::Directory(const std::string& name) : name(name)
{

}

void Directory::print(const std::string& indent) const
{
	std::cout << indent << name << "/" << std::endl;
	for (const auto& child : children)
	{
		child->print(indent + "\t");
	}
}

void Directory::addComponent(const std::shared_ptr<FileSystemComponent>& component)
{
	children.push_back(component);
}

3、调用

c 复制代码
auto root = std::make_shared<Directory>("root");
auto folder1 = std::make_shared<Directory>("folder1");
auto file1 = std::make_shared<File>("file1");
auto file2 = std::make_shared<File>("file2");
root->addComponent(folder1);
folder1->addComponent(file1);
root->addComponent(file2);
root->print("");
相关推荐
大肥羊学校懒羊羊2 分钟前
质因数个数问题:高效分解算法详解
开发语言·c++·算法
汪宁宇13 分钟前
(C++) Qt5.15.12 + GDAL库 等高线生成示例代码
c++·qt·等高线·gdal·等值线·rec533
sg_knight25 分钟前
设计模式实战:中介者模式(Mediator)
microsoft·设计模式·中介者模式
6Hzlia28 分钟前
【Hot 100 刷题计划】 LeetCode 155. 最小栈 | C++ 打包状态法 (最优雅的 O(1) 检索)
java·c++·leetcode
Kurisu_红莉栖40 分钟前
c++的复习——多态
开发语言·c++
geovindu41 分钟前
go: Prototype Pattern
开发语言·设计模式·golang·原型模式
草莓熊Lotso42 分钟前
手搓工业级 C++ 线程安全日志系统:基于策略模式解耦,兼容 glog 使用风格
linux·运维·服务器·数据库·c++·安全·策略模式
pearlthriving43 分钟前
STL容器及其底层
开发语言·c++·算法
Byte不洛1 小时前
深入理解C++多态机制:虚函数、虚表与对象内存模型解析
c++·多态·对象模型·虚函数表·虚基表
leaves falling1 小时前
C++ 继承详解:从入门到深入
开发语言·c++