代码之家  ›  专栏  ›  技术社区  ›  Matthew Stopa

依赖注入链是否是反模式?

  •  3
  • Matthew Stopa  · 技术社区  · 15 年前

    这就是问题所在,假设我们正在制作一个视频游戏,并希望使用依赖注入。以下是我们的产品:

    Game Class  // This is just the code to keep track of the overall game logic
    Character Class // This would be the guys in the game, good and bad guys both
    Weapon Class // The weapons for the characters
    

    所以通常当我进行依赖注入时,我会将地图上的当前位置和游戏状态注入到角色中,这样我的角色就可以知道在哪里创建自己,等等。然后我让角色创建武器并注入武器强度的值,以及其他一些来自游戏类等。

    在我看来,这几乎是一种反模式。我这么说是因为现在您有了(至少在我看来是这样的)非常脆弱和难以更改的代码。如果我们想更改传递的游戏状态信息,我们将被迫更改所有三个类。我们对游戏类做了最初的修改,然后修改角色,最后修改武器类。这是一个很大的工作,特别是如果你要深入5个层次,而不仅仅是3个层次。尽管是的,它允许比没有DI更容易进行单元测试。

    这听起来像是一种不好的做法。这是通常的做法吗?什么是我们有点“母舰”模式,一切都在顶层。所以不是游戏创造角色创造武器,而是让游戏(或其他类)创造所有的武器。

    这样,如果我们想给角色添加一个新的武器,游戏类只需创建武器本身并注入。不知道该怎么办。谢谢

    2 回复  |  直到 15 年前
        1
  •  2
  •   tster    15 年前

    设计问题很难回答,尤其是当这个例子似乎没有意义时。在这种情况下,角色创造武器是没有意义的。一个角色应该对那个角色负责。也许你可以为角色添加武器,但是,除非角色是武器制造者,否则我认为它不会真正创建一个新的武器类。

    顺便说一句,我认为比这两种模式中的任何一种更好的模式都是工厂模式。创建一个负责创建武器的类。以及负责创建字符的类。这样,如果在创建角色时有3个或4个位置需要更改,则该工厂可以处理该行为,并将其包含在以后的更改中。

        2
  •  5
  •   Mark Seemann    15 年前

    链接或嵌套依赖性是一个非常自然的实践(尽管我必须同意TSter的观点,您的示例听起来有点奇怪),但我认为我可以理解为什么您发现它是脆弱的——也就是说,如果您向其消费者注入具体的类型。

    技巧是在每个依赖级别引入一个接口,这样您就可以 独立于消费者的不同实施方式 . 作为示例,您应该定义 IGame 接口并将其注入 Character 类而不是 Game 类本身。

    即使如此,具有大量深嵌套的接口仍然可能很脆弱,因为您可能需要经常更改接口本身。这最好通过努力遵守 Hollywood Principle Law of Demeter 尽可能多。