组合模式【结构型模式C++】

1.概述

       组合模式又叫部分整体模式属于结构型模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。

2.结构

  • 组件(Component):定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等。
  • 叶子节点(Leaf):表示组合中的叶子节点对象,叶子节点没有子节点。它实现了组件接口的方法,但通常不包含子组件。
  • 复合节点(Composite):表示组合中的复合对象,复合节点可以包含子节点,可以是叶子节点,也可以是其他复合节点。它实现了组件接口的方法,包括管理子组件的方法。
  • 客户端(Client):通过组件接口与组合结构进行交互,客户端不需要区分叶子节点和复合节点,可以一致地对待整体和部分。

3.实现 

3.1 实例类比

      以电脑文件系统为例,其中有两种类型的文件:文本文件和文件夹。文本文件是叶子节点,文件夹是组合节点,可以包含其他文件。

     类体如下:

3.2 具体实现 
#include <iostream>
#include <string>
#include<vector>

using namespace std;
/**
 * Component抽象类,表示目录条目(文件+文件夹)的抽象类
 **/
class Component {

public:
	virtual string getName() = 0; //获取文件名

	virtual int getSize() = 0; //获取文件大小

	//添加文件夹或文件
	virtual Component* add(Component* entry) = 0;

	//显示指定目录下的所有信息
	virtual void printList(string prefix) {};
};


/**
 * File类 表示文件
 **/
class File :public Component {

private:
	string name_; //文件名
	int size; //文件大小

public:
	File(string name, int size) {
		this->name_ = name;
		this->size = size;
	}

	string getName() {
		return name_;
	}

	 int getSize() {
		return size;
	}

	 Component* add(Component* entry) {
		return nullptr;
	}

	  void printList(string prefix) {
		cout << prefix + "/" << name_ << endl;
	}

};


/**
 * Directory表示文件夹
 **/
class Directory :public Component {

	//文件的名字
private:
	string name_;

	//文件夹与文件的集合
	vector<Component*> directory;

public:
	//构造函数
	Directory(string name) {
		this->name_ = name;
	}

	//获取文件名称
	string getName() {
		return this->name_;
	}

     int getSize() {
		int size = 0;

		//遍历或者去文件大小
		for (auto it : directory) {
			size += it->getSize();
		}
		return size;
	}

	 Component* add(Component* entry) {
		directory.push_back(entry);
		return this;
	}

	//显示目录
      void printList(string prefix) {
		cout << prefix << "/" << name_ << endl;

		for (auto it : directory) {
			it->printList(prefix + "/" + name_);
		}
	}
};

int main()
{
	//根节点
	Directory *rootDir = new Directory("root");

	//树枝节点
	Directory *binDir = new Directory("bin");
	
	//向bin目录中添加叶子节点
	binDir->add(new File("test1", 1024));
	binDir->add(new File("test2", 2048));

	Directory *nginxlDir = new Directory("ngnix");
	Directory *confDir = new Directory("conf");
	nginxlDir->add(confDir);
	confDir->add(new File("nginx.conf", 30));
	
	rootDir->add(binDir);
	rootDir->add(nginxlDir);

	rootDir->printList("");
	return 0;
}

3.3运行结果 

4.状态设计模式优缺点

 优点: 

  1. 可以将对象组合成树形结构,表示整体-部分的层次关系。
  2. 可以统一处理单个对象和对象组合,简化了客户端的代码逻辑,提高了系统的可复用性
  3. 可以遵循开闭原则,扩展性高,增加新的节点类型时不需要修改原有代码。

缺点

      对于功能差异较大的类, 提供公共接口或许会有困难。 在特定情况下, 你需要过度一般化组件接口, 使其变得令人难以理解。

5 应用场景

  • 当需要表示一个对象整体与部分的层次结构时,可以使用组合模式来实现树形结构。例如,文件系统中的文件与文件夹、组织机构中的部门与员工、商品分类中的类别与商品等。
  • 当需要统一处理单个对象和对象组合时,可以使用组合模式来实现多态性。例如,图形界面中的简单控件与容器控件、菜单系统中的菜单项与子菜单、报表系统中的单元格与表格等。
  • 当需要将对象的创建和使用分离时,可以使用组合模式来实现依赖注入。例如,Spring框架中的Bean对象与BeanFactory对象、测试框架中的测试用例与测试套件等。

相关推荐

  1. 设计模式-组合模式Composite(结构

    2024-04-23 03:26:02       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-23 03:26:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-23 03:26:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-23 03:26:02       87 阅读
  4. Python语言-面向对象

    2024-04-23 03:26:02       96 阅读

热门阅读

  1. std::tuple介绍和使用

    2024-04-23 03:26:02       35 阅读
  2. 大语言模型对于“长序列”的处理方法

    2024-04-23 03:26:02       34 阅读
  3. RTT设备驱动框架学习(UART)

    2024-04-23 03:26:02       39 阅读
  4. vim之一键替换

    2024-04-23 03:26:02       37 阅读
  5. Vue3 ts使用echarts

    2024-04-23 03:26:02       39 阅读
  6. Vue + Cesium(之一)

    2024-04-23 03:26:02       32 阅读
  7. Vim是一款功能强大的文本编辑器

    2024-04-23 03:26:02       37 阅读
  8. Spring注解@ResponseBody的作用与应用场景

    2024-04-23 03:26:02       37 阅读
  9. zabbix

    zabbix

    2024-04-23 03:26:02      28 阅读
  10. element-ui组件封装技巧

    2024-04-23 03:26:02       33 阅读
  11. 微信小程序中前端 授权登录获取用户的openid

    2024-04-23 03:26:02       39 阅读