我已经绞尽脑汁想了两天了。简而言之,我正在制作一款游戏,并且针对武器和生命值实现了 2 个独立的逻辑。 (我试图使它们通用)这个概念是不存在这样的设备。该武器有一定数量的弹药,仅此而已。使用后,它会被扔掉,你会寻找另一件。我遵循这个逻辑。有一把武器,只有武器知道里面有多少子弹;玩家不应该知道任何事情;玩家的任务是在拿起武器并且有子弹的情况下重现射击。因此,任务是通过选择将哪些弹药筒添加到所使用的武器中来增加奖金。问题听起来是这样的。我不知道如何向武器添加弹药,以便拾取的弹药事先不知道武器(其他一切都一样)。我不想违反 SRP。请给我一些建议,让我朝哪个方向前进。我尝试应用访客模式并意识到它不属于这里。我也考虑过事件总线,但在我看来,它会导致同样的 SRP 违规,或者我在错误的方向上思考。
像这样的东西:
Weapon 类对 Ammo 类一无所知。虽然他有这样的权利,但既然谁用了墨盒呢?所以说是
public void AddAmmo(Ammo ammo)完全有可能做到的。Ammo 类对 Weapon 类一无所知,也不应该知道。如果 WeaponType 令人困惑,那么问题是,WeaponType 与 OOP 有什么关系? WeaponType 是data。
Player 类知道两者。既然他也有这个权利——谁拿起武器?谁来捡弹药?如果在你的情况下,玩家负责其他事情,那么创建几个类,例如 PlayerMovement 和 PlayerArsenal,甚至 Player、WeaponPicker 和 AmmoPicker,这样就不会违反 SRP。
SRP 并不是说一个类中的代码不应该接触另一个类。这是关于我们在一堂课上留下了什么以及我们在另一堂课上带了什么。也就是说,关于逻辑和数据应该或不应该在一起。
访问者模式与问题根本无关,因为它是一种主要用于处理遗留代码的模式,当您需要绕过(例如,在循环中)彼此不正式相关的对象时,深入探讨其实施细节。
事件、命令、反应性及其各种实现是为对象之间相互通信而创建的,是的。但在大多数情况下,它们的任务是当对象 A 知道对象 B 时断开双向连接,但反之则不然,并且通信必须在两个方向上进行。然后,一个对象调用另一个对象的方法,并以相反的方向进行通信,订阅更改。是的,有两个方向的通信实现,但为什么在这个特殊情况下会这样呢?这要解决什么实际问题?
是的,如果我们正在谈论减少代码一致性,那么我们可以使用接口来代替具体类型:
在这种情况下,从 OOP 的角度来看,Weapon 类不知道 Ammo 类,并且 Player 类不知道 Ammo 类或 Weapon 类。这样的抽象有必要吗?对于小项目 - 通常不是。对于一个大的 - 好吧,如果使用依赖注入,那么也许。嗯,Unity的可序列化字段对接口不友好。因此,如果您有 MonoBehaviours 并且通过 Inspector 连接依赖项,那么绝对不会。
可用的:
正确的?不是真的!还有很多持续的责任!有人拿起一些东西,有人把它全部放在某个地方,有人以某种方式使用它,有人进行可视化。物流也是演员,往往由几个环节组成,不仅在代码架构上,在生活中也是如此。
尽管武器和弹药筒不是库存物品,而是你拿起、使用和扔掉的消耗品,但实际上什么都不应该改变。抽象的要点是编写具有单一职责的小类来执行功能,并且不涉及整体实现的细节。
该单位有能力装备某些东西,并不关心它是什么。最主要的是,这个废话处于某种抽象之下
IHandsTakeable,它有一组用于输入和命令的方法。我不在乎它是武器还是你拖着一个盒子,我不在乎它来自哪里,从库存还是从地板上。我写了一篇关于物品选择的大文章。写信就足够了
IDropCollector,他的唯一责任就是弄清楚如何处理这种特定类型的战利品。附注
RequiredType这里的string键可能是"pistol"or"9x18mm",但在检查器中最好使用enum,这总是可能的.ToString(),以免手动编写字符串文字。但如果它是完全面向对象的,那么武器不应该有任何弹药筒总数,它应该只根据命令开火。它必须有一个委托(
Func<bool> shotCondition)来检查是否可以射击或将射击文件(播放空弹匣的声音)。如果shotCondition == null,那么武器将随心所欲地射击,例如在小怪手中。在其他情况下,这是一种检查库存中的物品或其他地方的数量的方法。武器的最大容量是弹匣中的子弹数量,这决定了何时需要重新装弹。也就是说,IHandsTakeable这个的本质不是Weapon实现这个接口的,而是它里面的包装器Weapon是它可以使用的墨盒数量。也就是说,该类
Weapon应该是这样的:如果它是从库存中发射弹药筒的库存物品,则它不会以任何方式改变,因为它具有相同的责任。每个人都通过接口相互沟通,没有人依赖任何人。
IHandsTakeable,Unit它可以与任何东西互动,甚至捡起一块鹅卵石并扔掉它。顺便说一句,它负责可视化UnitView,并且IHandsTakeable可能包含使用它时所需的动画的名称。DropCollector你甚至可以把它交给一个吸尘器,它有自己的吸尘器,IDropCollector它会像垃圾一样不加区别地销毁所有物体。TakeableWeapon您甚至可以将其安装在炮塔或装饰品上,与所有者没有任何联系,并且在破坏后,该塔可以由角色拾取。