【设计模式】组合模式(Composite)

目录

一、问题导入

二、代码实现

三、课件内容(我个人认为内容模糊且交叉,有些地方我认为是不准确或者是不正确的)

1.为什么用(Why)

2.什么时候用(When)

3.怎么用(How)

4.锐评

四、优劣

1.优势

2.劣势

五、个人补充


前言:该设计模式在我的另一篇**【OpenGL】父子级关系** 中也做了一定的阐述,本文有一部分阐述全都由那篇文章拷贝而来。感兴趣的可以去看一下【OpenGL】父子级关系-CSDN博客

一、问题导入

组合模式 是一种树形结构,通过扩充子节点的方式将整体与部分组合起来,不仅可以通过遍历 更新所有子节点,还可以通过递归的形式将整体的行为逻辑施加给子节点。

试着去移动我们的手臂,平移大臂,此时小臂会跟着大臂一起移动,接着弯曲小臂,大臂并不会随着小臂移动。这个时候,大臂的具体状态就是其经过平移后的位置,而小臂则是小臂弯曲与大臂平移的叠加后的位置。这个时候小臂为"子",而大臂为"父","父"的变化会牵连着所有的"子",反之不行。(骨骼动画便是这样的典型应用)

二、代码实现

这样的组合模式是一个树形结构,每一个抽象的Object都会连着若干个Object

值得欣慰的是,这种结构的实现相当简单!

cpp 复制代码
//树形结构组件
class Object
{
public:
	//添加子节点
	void add_child(Object* child) { children.push_back(child); }
	virtual void on_update()
	{//更新所有子节点
		for (auto child : children)
			child->on_update();
	}
private:
	std::vector<Object*> children;//容器存储子节点
};

大小臂移动的实例代码:(在这里,将小臂作为大臂的一个子节点,那么当进行大臂的更新的时候,就会同时更新小臂)

cpp 复制代码
#pragma once

#include<iostream>
#include<vector>

namespace _CompositePattern
{ 
	//树形结构的地基
	class Object
	{
	public:
		//添加子节点
		void add_child(Object* child) { children.push_back(child); }
		virtual void on_update()
		{//更新所有子节点
			for (auto child : children)
				child->on_update();
		}
	private:
		std::vector<Object*> children;//容器存储子节点
	};
	//小臂
    class ForeArm : public Object
	{
	public:
		void on_update() override
		{
			std::cout << "小臂移动" << std::endl;
			Object::on_update();
		}
	};
	//大臂
	class UpperArm : public Object
	{
	public:
		void on_update() override
		{
			std::cout << "大臂移动" << std::endl;
			Object::on_update();
		}
	};
	
	void test()
	{
		Object* upper_arm = new UpperArm();
        Object* fore_arm = new ForeArm();
		//将小臂链接到大臂上
        upper_arm->add_child(fore_arm);
        //移动大臂,此时小臂也会移动
		upper_arm->on_update();
        delete upper_arm;
        delete fore_arm;
	}
}

运行结果:

三、课件内容(我个人认为内容模糊且交叉,有些地方我认为是不准确或者是不正确的)

1.为什么用(Why)

(1)将对象组合成树形结构,以表示部分 - 整体的层次结构。组合模式使得用户对单个对象和组合对象的使用保持一致。

(2)将复杂元素当作简单元素来处理,从而使客户端程序与复杂元素的内部结构解耦。

2.什么时候用(When)

(1)树枝和树叶实现统一的接口,树枝在内部组合该接口。

(2)该接口在树枝内部组装,并包含内部属性列表,列表中放置组件(Component)。

3.怎么用(How)

(1)树枝和树叶实现统一的接口,树枝在内部组合该接口。

(2)该接口在树枝内部组装,并包含内部属性列表,列表中放置组件(Component)。

4.锐评

英雄所见略同

四、优劣

1.优势

(1)高层模块调用简单。

(2)节点可自由增加(符合开闭原则,OCP)。

2.劣势

(1)难以给功能差异过大的类提供通用接口。

(2)树叶和树枝都是实现类(违反依赖倒置原则,DIP)。(个人存疑)

五、个人补充

组合模式 的应用十分广泛,包括文件系统、骨骼动画,以及各类渲染引擎和游戏引擎的场景结构。这种设计模式巧妙地通过统一接口,实现了客户端与节点结构的解耦,让我们操作节点时(比如删除文件夹、移动骨骼),不用区分操作的是整体(父节点)还是部分(子节点),也不用手动处理它们的联动逻辑。

相关推荐
七月丶16 小时前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞16 小时前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼16 小时前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟1 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder1 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室2 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦2 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo6 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4966 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃6 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式