关于 Unity3D SOLID SRP 的建议

Advice on Unity3D SOLID SRP

我目前正在使用 Unity3D 制作游戏,并在学习过程中尝试将 SOLID 的单一职责原则应用到我的游戏中。

我想知道是否有人可以进一步解释 SRP 的良好实施是什么样的,因为我觉得我正在打破它。

我已将 classes 分解为基础部分:

当我开始时,我觉得我在遵循 SRP,但现在游戏变得越来越复杂。上面列出的每个 class 都得到了对其他人的引用,这似乎是不必要的。我在每个 class 中使用了 5 个 GetComponents,这似乎是重复的,因为它们都在同一个对象上。换句话说,SRP 似乎需要更多的工作,并且正在降低效率。

例如,PlayerController 和 PlayerMovement 脚本都引用了 AnimationController,其中 AnimationController 也引用了两者。所有脚本都引用了 PlayerInput。 (请记住,为了保持简单,我省略了其他玩家相关的脚本,如工艺和设备,但我的 Start 和 Awake 方法充满了一堆 GetComponent 调用)

任何人都可以向我更好地解释 SRP 并为我指明正确的方向,这样我就不会在同一个 GameObject 上过多地使用 GetComponent 了。

谢谢

听起来你所说的与 SRP 无关。在最基本的情况下,SRP 意味着您拥有的任何 class 都应该只是 "responsible" 的一件事。您的 PlayerInput 负责跟踪玩家通过其接口设备提供的内容,PlayerController 根据多种因素提供有关玩家的状态信息,等等。

您所指的似乎与 DRY(不要重复自己)原则更相关。 DRY 很棒,它为抽象和代码重用提供了很好的 backbone,但它不是福音。事实上,SOLID 原则之一——依赖倒置原则——在某些方面积极鼓励人们以灵活性的名义重复自己。

如果您认为自己对方法的调用过多,可以考虑将对该方法的一系列调用和任何调解逻辑包装在另一个方法中,然后改为调用该方法。当然,这取决于需要在多个地方调用同一组指令。

现在,我要说的是,您的 post 中跳出的部分是您的 AnimationControllerPlayerController 以及 PlayerMovement 之间的循环引用classes。这 实际上 违反了 SRP 和其他一些良好设计原则,因为随附的 classes 现在负责分配给它们的任务,并且在最重要的时候至少,跟踪 AnimationController 中发生的事情,最多调用 AnimationController 本身的方法。

您应该考虑重构更细粒度的 classes,这样无论 AnimationController 中发生了什么,它们都能够完成自己的工作,反之亦然。封闭的 class 应该处理告诉封闭的 class 做什么的逻辑,本质上是为封闭的 class.

做出决定

你已经正确地找到了问题,这个问题显然是需要解决的,不管理论上的原理。不过好吧,让我们先讨论一下 SRP:

SRP 引用了两个较旧的概念,即 耦合内聚。不幸的是,名称 "SRP" 令人困惑、模棱两可,并且只包含等式的一侧,即拆分内容。它没有提到属于一起的东西实际上应该在一起。

因此,所有这一切的目的是实现 可维护性 ,这是 shorthand 创造更少的未来工作。为此,相互引用的事物实际上应该放在一起似乎是合理的。这意味着处理某些数据的方法应该与该数据位于同一位置(即在同一个对象中)。松散相关的东西(即很少相互提及)应该分开。

如何在实践中做到这一点取决于业务案例,并不总是很明显。我建议练习。将这些东西放在一个 class 中,例如将其命名为 Player。简化它,删除所有 setter/getters 和间接寻址。然后尝试查看是否存在仅松散地相互引用的区域,或者仅在一个方向上引用的区域。这些将是很好的拆分对象。

尝试拆分有意义的东西而不是技术性的东西,即MovementAttackPlayer都很好,ControllerAnimation是有问题(虽然并不总是坏事)。