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

本文通过一个电商超市购物的例子,详细解释了组合模式(Composite Pattern)的概念和工作原理。组合模式用于组织对象,形成树形结构,使得部分和整体可以统一操作。文中展示了如何创建抽象基类Object,以及子类Box(非叶子节点)和Commodity(叶子节点)的实现,最后通过一段代码展示了如何组合这些对象并计算总价。
摘要由CSDN通过智能技术生成

一、简介

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

 上图中的对象组:

红色的对象是包含其他的对象组的对象,在树状结构中,为非叶子节点

黑色的对象是不再包含其他对象组的对象,在树状结构中,为叶子节点

组合模式创建了一个可以包含自己对象组的类。该类提供了修改或查询相同对象组的方式。

二、实例

【项目说明】

上述描述可能比较抽象, 我们使用生活中的一个例子说明:(可以结合下面代码理解)

假如某顾客在某电商超市里购买了一系列物品(3支牙刷、一件方便面、洗手液一瓶、书籍3本:C++沉思录、C和指针、计算机网络),超市老板在拣货过程中,对该顾客的购买物品进行打包处理(把3支牙刷放到一个盒子,3本书放到一个盒子里,其他物品不再打包,最后把所有物品放入快递箱子)。

例如这种复杂的订单,我们可以把其拆分为为各部分组成:

包含商品等的盒子(下列代码中的Box类),类似非叶子节点

商品(下列代码中的Commodity类),类似叶子结点

并且不同结构的部分可以使用一通用结构物品(Object)表示

Box和Commodity都是Object,这样,组合模式就能使用Object类将所有对象组合成树状结构,并且能像使用独立对象一样使用它们。

我们知道每件商品都具有价格属性,作为单独的对象,无论是Box或Commodity,都能利用递归查询内包含的对象列表_objList的方式单独获取该对象的价值。

【代码实现】

1)抽象基类-Object  提供一种通用结构,声明子类可以实现的行为


class Object
{
public:
	virtual ~Object() {}
	virtual void add(Object *obj) {};
	virtual void remove(Object *obj) {};
	virtual double showAndPrice() = 0;
};

2)子类Box类,继承Object。作为非叶子节点,具有对象列表_objList,并实现添加和删除其他Object对象的功能

class Box : public Object
{
public:
	Box(string name) : _boxName(name){}
	~Box() {}

	void add(Object *obj)
	{
		_objList.push_back(obj);
	}
	void remove(Object *obj)
	{
		_objList.remove(obj);
	}
	double showAndPrice()
	{
		cout << "包裹-" << _boxName << ":" << endl;
		double price = 0;
		for (auto it : _objList)
		{
			price += it->showAndPrice();
		}
		cout << "共" << price << "元" << endl << endl;
		return price;
	}

private:
	string _boxName;  //盒子名称
	std::list<Object*> _objList;  //内容物列表
};

3)商品类Commodity,继承Object。作为叶子结点,没有可以包含其他对象的功能,所以没有内容对象列表,但是具有价格属性

//单件商品
class Commodity : public Object
{
public:
	Commodity(string name, double price) 
		:_name(name)
		,_price(price) {}

	double showAndPrice()
	{
		cout << "商品:" << _name << "  " << _price << "元" << endl;
		return _price;
	}
private:
	string _name;  //商品名称
	double _price; //商品价格
};

4)使用


int main(int argc, char *argv[])
{
	//某顾客购物清单
	Object* cd1 = new Commodity("牙刷A", 3.5);
	Object* cd2 = new Commodity("牙刷B", 3.5);
	Object* cd3 = new Commodity("牙刷C", 3.5);
	Object* cd4 = new Commodity("X牌方便面", 20);
	Object* cd5 = new Commodity("洗手液", 15.8);
	Object* cd6 = new Commodity("书籍:C++沉思录", 38);
	Object* cd7 = new Commodity("书籍:C和指针 ", 32);
	Object* cd8 = new Commodity("书籍:计算机网络 ", 65);

	//商店打包:书籍放一个箱子
	Object* box1 = new Box("书籍箱子");
	box1->add(cd6);
	box1->add(cd7);
	box1->add(cd8);
	//商店打包:牙刷放一个盒子
	Object* box2 = new Box("牙刷盒子");
	box2->add(cd1);
	box2->add(cd2);
	box2->add(cd3);
	//其他物品不再另行包装
	//打包成一个箱子快递邮走
	Object* box = new Box("快递箱子");
	box->add(box1);
	box->add(box2);
	box->add(cd4);
	box->add(cd5);

	//查看购物清单

	cout << "总价格为:" << box->showAndPrice() << endl;

	system("pause");
	return 0;
}

5)运行结果

 

 

【参考&致谢】

C++组合模式(Composite)_紫荆鱼的博客-CSDN博客_c++ compositehttps://blog.csdn.net/m0_46655373/article/details/123951107

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值