所有(OOP)依赖项的根存储在哪里?
Posted
技术标签:
【中文标题】所有(OOP)依赖项的根存储在哪里?【英文标题】:Where is the root of all (OOP) dependencies stored? 【发布时间】:2019-12-21 18:29:54 【问题描述】:我正在学习 C# 以及围绕它的最佳实践。
现在我知道了:
-
单一职责原则
静态类
单例
依赖注入
大家都说要避免 Singleton 和 Static,而更喜欢依赖注入。
现在我已经转换了我的所有类,这样他们就不必获取自己的数据,例如删除:
_myItem = Repository.Instance.FindById(1);
而是在 MyClass 中注入我的依赖项。
public MyClass(Repository repository)
_myItem = repository.FindById(1);
但是,既然 MyClass 遵循单一职责原则,并从 MyClass 外部获取所有依赖项,那么什么/哪个类将负责提供所有依赖项?
我在 Unity 中的示例问题是:
UIStatusPanelClass 依赖于 CurrentCharacter。 GameInputClass 依赖于 CurrentCharacter 和 CurrentCamera。 CharacterManagerClass 保存 CurrentCharacter,但不负责传递给其他类,因为它的唯一职责是保存场景中的所有角色。 UIInventoryClass 依赖于由 CurrentCharacter 持有的 InventoryClass。 StatisticClass 取决于 CurrentCharacter。 ItemRepositoryClass 负责持有 List 但不负责获取项目。请帮助我理顺我对这些事情的了解。
【问题讨论】:
“每个人都说要避免 Singleton 和 Static”你可能有点误解了。通常,最好使用单例 over static。但不能避免两者。尽管如此,static
仍然占有一席之地。回答您的问题:使用 DI 框架来传递您的依赖项。此外,一种常见的模式是将它们注入到类构造函数中
我同意@OlegI。我想我知道 a thing or two 关于依赖注入,但我仍然在我的代码库中使用静态。但是,当您应用 DI 时,您需要区分 stable and volatile dependencies。需要注入 Volatile,stables 可以是静态的,甚至可以使用 Singleton 设计模式实现。然而,对 volatile 依赖项 使用 Singleton 设计模式是一种反模式。
区分单例设计模式和单例生活方式也很重要。您可以阅读更多关于差异的信息,here。
您好,您的所有参考资料确实对新开发人员有所帮助。我一直在手动将很多依赖项推送到入口点附近,我很确定应该有更好的方法。也许稍后我会使用 DI 容器/框架。然而另一个问题:如果我使用单例来获取数据,然后在课堂上使用它,这会破坏 SRP 吗?除了履行自己的职责之外,该班级还负责获取数据。
【参考方案1】:
既然 MyClass 遵循单一职责原则,并从 MyClass 外部获取所有依赖项,那么什么/哪个类将负责提供所有依赖项?
这是Composition Root的功能:
组合根是应用程序中的(最好)唯一位置,模块组合在一起。
组合根位于应用程序根内。
DI Container 是一个有用但可选的工具,可以扮演组合引擎的角色。在没有 DI 容器的情况下应用 DI 是一种称为Pure DI 的做法。如果您使用 DI 容器,它可以被视为 您的合成根目录的一部分。
关于以下代码的警告:
public MyClass(Repository repository)
_myItem = repository.FindById(1);
在练习 DI 时,注入构造函数应该没有任何逻辑,应该做nothing more than just store their incoming dependencies。这意味着您不应该从MyClass
的构造函数中调用FindById
。这应该在稍后阶段完成;在MyClass
的方法之一中。
【讨论】:
以上是关于所有(OOP)依赖项的根存储在哪里?的主要内容,如果未能解决你的问题,请参考以下文章