前端设计模式 - 树对象结构与订阅发布者模式 Unity与Qt【极简版】

news/2025/11/7 11:13:19/文章来源:https://www.cnblogs.com/qiuliw/p/19199109

树本身很好的体现了对象的层级与局部性,在此基础上很容易应用各种设计模式

树结构中,每个节点(TreeNode)可同时作为发布者订阅者

  • 订阅者:节点可以订阅其他节点(通常是父节点或祖先节点)的特定事件(如状态变更、数据更新)。
  • 发布者:节点状态变化时,向所有订阅者(通常是子节点或后代节点)发布事件,触发响应逻辑。

通过这种双向通信机制,树节点无需硬编码依赖彼此的引用,只需通过事件接口交互,降低耦合度。

Qt 如何体现我们的设计原则

通过订阅-发布者模式,树结构的节点通信从“硬依赖”转变为“松耦合”,尤其适合复杂UI组件(如树形控件、组织架构图)或数据结构(如AST语法树)的设计。、

[!question] 为什么父不订阅子对象信号而直接调用或委托

  1. 父对象对子对象本就有一种隐式的依赖,直接调用或者 委托(强引用)可以减少 消息&事件 带来的性能损失,同时简单调用链可直接追踪。
    对于需要编译时语言通常如此,对于运行时语言就不一定了,一般也是用的信号传递,因为父对象可能也不预先知道他有几个子对象,无法强引用
  2. 子对象不确定他属于哪个父对象或者爷爷对象,所以需要使用 消息&事件 保持解耦。同时对于非局部要向外扩展的消息可以利用事件系统广播

Qt 中的两种通信方式

1. 直接调用方法(父对子)

// 父对象直接调用子对象的方法
QWidget* parent = new QWidget;
QPushButton* button = new QPushButton("Click me", parent); // 父子关系// 父对象直接调用子的方法 - 不需要信号槽
button->setText("New Text");
button->setEnabled(false);
button->move(100, 100);

2. 信号槽机制(子对父/跨对象)

// 子对象通过信号通知父对象(不确定的监听者)
class MyWidget : public QWidget {Q_OBJECT
public:MyWidget() {QPushButton* button = new QPushButton("Click me", this);// 父对象订阅子的信号connect(button, &QPushButton::clicked, this, &MyWidget::onButtonClicked);}private slots:void onButtonClicked() {// 响应子对象的信号qDebug() << "Button was clicked!";}
};

Qt 如何体现我们的设计原则

原则1:父直接调用子(性能+精确控制)

// 父窗口直接操作子控件
QMainWindow* window = new QMainWindow;
QStatusBar* statusBar = new QStatusBar(window);// 直接调用 - 高效、精确
statusBar->showMessage("Loading...");
statusBar->setSizeGripEnabled(true);// 布局管理也是直接调用
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(new QPushButton("OK"));
layout->addWidget(new QPushButton("Cancel"));

原则2:子通过信号通知父(解耦)

// 按钮不知道谁会响应它的点击
// 可能是直接父级、祖父级、甚至是完全无关的对象
QPushButton* button = new QPushButton;// 多个可能的监听者
connect(button, &QPushButton::clicked, dialog, &QDialog::accept);
connect(button, &QPushButton::clicked, logger, &Logger::logButtonClick);
connect(button, &QPushButton::clicked, analytics, &Analytics::trackEvent);

Unity 中的通信方式与设计原则

Unity 的设计哲学与 Qt 类似,但具体实现机制不同。让我展示 Unity 中如何体现同样的设计原则:

Unity 中的两种通信方式

1. 直接调用方法(父对子)

// 父对象直接调用子对象的方法
public class ParentController : MonoBehaviour
{private ChildComponent child;void Start(){// 获取子对象的引用child = GetComponentInChildren<ChildComponent>();// 或者通过Transform查找// child = transform.Find("ChildObject").GetComponent<ChildComponent>();}void Update(){// 父对象直接调用子的方法child.UpdatePosition(new Vector3(10, 0, 0));child.SetEnabled(true);child.ChangeColor(Color.red);}
}public class ChildComponent : MonoBehaviour
{public void UpdatePosition(Vector3 newPos){transform.position = newPos;}public void SetEnabled(bool enabled){gameObject.SetActive(enabled);}public void ChangeColor(Color color){GetComponent<Renderer>().material.color = color;}
}

2. 事件系统(子对父/跨对象)

// 子对象通过事件通知父对象
public class ButtonController : MonoBehaviour
{// 定义事件public event System.Action OnButtonClicked;public event System.Action<int> OnValueChanged;void Update(){if (Input.GetMouseButtonDown(0)){// 触发事件,不知道谁会监听OnButtonClicked?.Invoke();}}public void SetValue(int value){// 触发值变化事件OnValueChanged?.Invoke(value);}
}public class UIManager : MonoBehaviour
{void Start(){// 父对象订阅子对象的事件ButtonController button = FindObjectOfType<ButtonController>();button.OnButtonClicked += HandleButtonClick;button.OnValueChanged += HandleValueChange;}void HandleButtonClick(){Debug.Log("Button was clicked!");}void HandleValueChange(int newValue){UpdateUI(newValue);}
}

Unity 如何体现设计原则

原则1:父直接调用子(性能+精确控制)

// 父对象直接操作子对象
public class GameManager : MonoBehaviour
{public PlayerController player;public EnemySpawner spawner;public UIScoreDisplay scoreDisplay;void StartGame(){// 直接调用 - 高效、精确控制player.ResetPosition();player.SetHealth(100);spawner.StartSpawning();scoreDisplay.ResetScore();}void EndGame(){// 直接停止所有子系统spawner.StopAllCoroutines();player.DisableControls();scoreDisplay.ShowGameOver();}
}

原则2:子通过事件通知父(解耦)

// 子对象不知道谁会监听它的事件
public class HealthComponent : MonoBehaviour
{public event System.Action<float> OnHealthChanged;public event System.Action OnDeath;private float currentHealth = 100;public void TakeDamage(float damage){currentHealth -= damage;OnHealthChanged?.Invoke(currentHealth);if (currentHealth <= 0){OnDeath?.Invoke();}}
}// 多个可能的监听者
public class PlayerUI : MonoBehaviour
{void Start(){HealthComponent health = GetComponent<HealthComponent>();health.OnHealthChanged += UpdateHealthBar;}void UpdateHealthBar(float health) { /* 更新血条UI */ }
}public class AchievementSystem : MonoBehaviour
{void Start(){HealthComponent health = FindObjectOfType<Player>().GetComponent<HealthComponent>();health.OnDeath += UnlockDeathAchievement;}void UnlockDeathAchievement() { /* 解锁成就 */ }
}public class SoundManager : MonoBehaviour
{void Start(){HealthComponent health = FindObjectOfType<Player>().GetComponent<HealthComponent>();health.OnHealthChanged += PlayHurtSound;}void PlayHurtSound(float health) { /* 播放受伤音效 */ }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/958630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

问题记录,unity shaderlab 模版写入问题

当使用 clip 裁剪 alpha 丢弃扣模版的时候 一般 ZWrite Off, ZTest Always 这时, 在某些三星手机上,clip 的像素但是并不能阻止模版写入。 需要把 ZWrite On 开启。

2025年11月园区车辆管理系统推荐榜:五强对比评测与选型指南

如果您正在负责园区运营、物流调度或安全管控,大概率会遇到以下场景:货车排长队导致园区道路拥堵,司机反复电话确认进园时间,安保人工核对车辆信息效率低,月台空置与拥堵交替出现,数据分散在ERP、地磅、门禁多个…

2025年11月中国AI关键词排名优化公司榜:五强实测数据与口碑排名

当品牌发现“在DeepSeek、豆包、Kimi里搜不到自己”时,焦虑随之而来:AI对话正取代传统搜索,谁先被大模型提到,谁就拿到订单。2025年三季度工信部《生成式AI搜索生态观察》显示,已有68%的B2B采购决策者“优先用AI提…

Linux-> TCP 编程2 - 指南

Linux-> TCP 编程2 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", …

《投资-99》价值投资者的认知升级与交易规则重构 - 什么是周期性股票?有哪些周期性股票?不同周期性股票的周期多少?周期性股票的买入和卖出的特点? - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

dockerfile 加入变量同步容器时间

dockerfile 加入变量同步容器时间方法二:Dockerfile解决方案 复制代码 # 方法1 # 添加时区环境变量,亚洲,上海 ENV TimeZone=Asia/Shanghai # 使用软连接,并且将时区配置覆盖/etc/timezone RUN ln -snf /usr/share…

2025年新店微信朋友圈推广权威推荐榜单:腾讯朋友圈推广/腾讯朋友圈广告开户/微信朋友圈本地推广源头服务商精选

随着线下商业的快速复苏,新店开业如何快速引爆市场成为经营者面临的首要挑战。微信朋友圈广告作为一种精准触达本地客群的推广方式,因其高达80%以上的打开率和强社交属性,已成为新店开业营销的标配工具。 本文将基于…

【URP】Unity[后处理]镜头畸变LensDistortion

Lens Distortion 效果概述 Lens Distortion 是 Unity URP 后处理系统中的核心组件之一,用于模拟真实相机镜头的光学畸变现象。这种效果通过扭曲渲染画面边缘,能够创造【从UnityURP开始探索游戏渲染】专栏-直达Lens D…

初学:运用工具进行SQL注入

基础 常见数据库语言: database -- db --数据库 table -- T -- 数据表 column -- C -- 数据列 初学:使用工具进行SQL注入 工具:sqlmap.py 步骤 1.找交互点 2.验证注入点 3.挖数据库名称 4.挖数据表名称 5.挖数据列…

2025年中频熔炼炉厂家推荐:浙江湘达机电,铜中频熔炼炉/铝中频熔炼炉/金中频熔炼炉/银中频熔炼炉/覆盖多金属加工场景

随着制造业数字化转型加速、环保能效标准趋严及高端金属加工需求增长,中频熔炼炉作为金属加热与熔化的核心设备,已在机械制造、汽车、有色金属等行业实现广泛应用,2025 年市场规模预计保持稳健扩张。但市场升温也导…

2025 年 11 月尼龙板厂家推荐排行榜,防静电尼龙板,透明尼龙板,白色尼龙板,优质尼龙板公司推荐

2025年11月尼龙板厂家推荐排行榜:防静电尼龙板、透明尼龙板、白色尼龙板优质供应商深度解析 工程塑料作为现代工业的重要基础材料,在机械制造、电子电气、汽车工业等领域发挥着不可替代的作用。其中尼龙板以其优异的…

爱思益联系方式: 理性评估服务与费用

官方联系方式 客服电话:4000559882 总部地址:北京市朝阳区(具体门牌以官网披露为准) 官网域名:aceoffer.cn(工信部备案号可在底部查询) 微信公众号:爱思益AceOffer(账号主体北京爱思益咨询有限公司) 商务合作…

2025年升降压充电管理IC权威推荐榜单:镍氢电池充电管理IC/铅酸电池充电管理IC/升压充电芯片源头厂家精选

随着便携式电子设备、物联网终端及新能源应用的快速发展,升降压充电管理IC作为电源管理的核心元件,其市场需求持续增长。据行业分析数据显示,全球电源管理芯片市场规模在2024年已达到约450亿美元,其中升降压充电管…

docker 修改默认IP段

mtli:/etc/docker# cat /etc/docker/daemon.json {"registry-mirrors": ["https://harbor.rd.in.linx"],"insecure-registries": ["https://harbor.rd.in.linx"],"bip&…

2025年靠谱的静态扭矩传感器高评价厂家推荐榜

2025年靠谱的静态扭矩传感器高评价厂家推荐榜 在工业自动化、智能制造和精密测量领域,静态扭矩传感器作为关键测量元件,其精度、稳定性和可靠性直接影响生产效率和产品质量。随着2025年中国制造业智能化升级的加速推…

2025年比较好的不锈钢阀厂家推荐及选择指南

2025年比较好的不锈钢阀厂家推荐及选择指南 不锈钢阀门因其耐腐蚀、耐高温、耐高压等特性,广泛应用于石油、化工、电力、食品、医药等行业。随着工业技术的不断发展,市场对不锈钢阀门的需求也在持续增长。2025年,如…

2025年11月中国抗衰老设备技术排行榜TOP10:科技抗衰新趋势解析

摘要 随着人口老龄化加剧和健康意识提升,中国抗衰老行业在2025年迎来快速发展期。光疗技术与高低氧训练等创新方案成为市场热点,本文基于技术先进性、临床效果和用户口碑维度,对当前主流抗衰老设备进行综合排名,为…

2025年靠谱的薄壁不锈钢管厂家最新推荐权威榜

2025年靠谱的薄壁不锈钢管厂家最新推荐权威榜行业概述薄壁不锈钢管作为现代建筑装饰、工业制造和家居装修的重要材料,凭借其优异的耐腐蚀性、高强度、美观性和环保特性,已成为管道材料领域的首选。随着2025年建筑行业…

爱思益联系方式: 如何验证信息真伪

一、官方联系方式 客服电话:4000559882 总部地址:北京市朝阳区建国门外大街甲6号中环世贸中心D座(可地图核验) 官网:可在公开搜索引擎以“爱思益 AceOffer”检索,域名以aceoffer开头,结尾为.com 微信公众号:同…

2025年抗衰老品牌哪家靠谱?Top5分析

摘要 随着人口老龄化加剧和健康意识提升,抗衰老行业在2025年迎来爆发式增长,复合年增长率预计达15%。消费者对安全、有效的抗衰老解决方案需求激增,推动技术创新和市场分化。本文基于权威数据和分析,为您呈现2025年…