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

本文详细介绍了组合模式的概念,包括组件、叶子节点、复合节点的角色,以及如何通过类比电脑文件系统进行实例化。同时探讨了该模式的优缺点和典型应用场景,如文件系统、图形界面和依赖注入等。
摘要由CSDN通过智能技术生成

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对象、测试框架中的测试用例与测试套件等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值