面向对象设计原则系列(7):组合复用原则(CRP)
在面向对象设计中,继承 经常被滥用:你可能从 BaseEnemy 继承再派出 Goblin、Orc、Dragon,然后又从 FlyingEnemy 继承 Wyvern、Harpy……当层级不断增加,系统易陷入“继承地狱”,修改一个父类往往波及所有子类。组合复用原则(Composite Reuse Principle,CRP) 提倡:优先使用对象组合/聚合,而非继承,让你在保持灵活性的同时,降低耦合、提高内聚。
加载过慢请开启缓存 浏览器默认开启
在面向对象设计中,继承 经常被滥用:你可能从 BaseEnemy 继承再派出 Goblin、Orc、Dragon,然后又从 FlyingEnemy 继承 Wyvern、Harpy……当层级不断增加,系统易陷入“继承地狱”,修改一个父类往往波及所有子类。组合复用原则(Composite Reuse Principle,CRP) 提倡:优先使用对象组合/聚合,而非继承,让你在保持灵活性的同时,降低耦合、提高内聚。
在 Unity 项目中,随着功能模块增多,业务逻辑往往依赖于大量低层实现——比如 UI 直接引用数据访问层、游戏对象硬编码查找具体组件、系统模块相互 new 实例化等
在中大型项目中,为了统一管理,常常会将多种方法捆绑在一个接口里,结果,并非所有实体都需要这些方法:NPC 不会被“拾起”,道具不需要“逻辑更新”和“渲染”接口。这样的“胖接口”会导致实现类必须提供空方法,或者客户端依赖不需要的方法
在 Unity 项目中,继承常被用来复用代码:你可能有一个 Enemy 基类,再派生出 Goblin、Orc、Dragon。但当子类在行为上偏离父类预期时,就会导致难以发现的 Bug:比如某个子类在调用 TakeDamage() 后不减少生命值,或者重写了移动逻辑却在特定情况下抛出异常。里氏替换原则(Liskov Substitution Principle, LSP)正是为了解决这类问题,它告诉我们:子类必须能够替换父类,并保持系统的正确性。
在 Unity 项目中,你常常会被频繁变动的需求折磨——新武器、新技能、新 AI 行为不断涌现。如果你把所有逻辑都写在一个 if–else 或 switch 语句里,每次新增功能都要打开原有类进行修改,不仅容易引入 Bug,还会造成回归测试负担。开闭原则 (Open/Closed Principle, OCP) 正是为了解决这一痛点:对修改关闭,对扩展开放,让系统在不修改已有代码的前提下平滑地新增功能。
在复杂的软件系统中,随着功能不断增加,一个类往往承担了验证、业务逻辑、持久化、日志、UI 更新等多重职责。这样的“上帝类”(God Class)不仅难以理解,也难以测试、扩展和维护。单一职责原则(SRP,Single Responsibility Principle)告诉我们——一个类/模块应该只有一个导致它变化的原因。 本文将从识别职责、高内聚设计、重构实战、度量与工具等角度,深入探讨 SRP 的核心技术要点和落地策略。
在复杂的软件系统中,需求不断变化,功能不断迭代,如果没有一套成熟的设计原则作指导,代码往往会随着时间演化成“烂泥”——高耦合、低内聚、扩展困难、测试无从下手。面向对象设计(OOD, Object-Oriented Design)的七大原则,正是几十年实践中沉淀出的“设计金律”,它们关注如何 划分职责、管理依赖、限制变更影响,确保系统具备可维护性、可扩展性和可测试性。
近期需求需要用到WPF装饰器,而WPF有三个常用的“装饰器”相关类,故对其进行对比分析记录
关于MySQL 8.0 默认使用了新的身份验证插件 caching_sha2_password,而旧版本的 MySQL Connector/NET 不支持该插件的问题