Sys*_*min 75 oop design-patterns dependency-injection
我们如何确定何时使用依赖注入或单例模式.我在很多网站上都读到过"使用依赖注入超过单一模式"的网站.但我不确定我是否完全赞同他们.对于我的中小型项目,我肯定会看到单例模式的使用直截了当.
例如Logger.我可以使用Logger.GetInstance().Log(...)
But,而不是这个,为什么我需要使用logger的实例注入我创建的每个类?
Bry*_*tts 84
单身人士就像共产主义:他们在纸上听起来都很棒,但在实践中却有问题.
单例模式过分强调访问对象的难易程度.它通过要求每个消费者使用AppDomain范围的对象完全避开上下文,不为不同的实现留下任何选项.它将基础设施知识嵌入到您的课程中(对呼叫GetInstance()),同时添加完全零的表达能力.它实际上减少了你的表达能力,因为你不能改变一个类所使用的实现而不改变所有类的实现.您根本无法添加一次性功能.
此外,当类Foo依赖时Logger.GetInstance(),Foo有效地将其依赖性隐藏在消费者之外.这意味着你无法完全理解Foo或使用它,除非你阅读它的来源并揭示它依赖的事实Logger.如果您没有源代码,则会限制您理解和有效使用您依赖的代码的程度.
使用静态属性/方法实现的单例模式只不过是实现基础结构的黑客攻击.它以无数种方式限制了你,同时对替代方案没有任何明显的好处.您可以随意使用它,但由于有可行的替代方案可以促进更好的设计,因此绝不应该是推荐的做法.
Pét*_*rök 17
其他人已经很好地解释了单身人士的问题.我想添加一个关于Logger特定情况的说明.我同意你那它通常是不访问一个Logger(或根记录器,更确切地说),为单一的问题,通过一个静态getInstance()或getRootLogger()方法.(除非你想看看你正在测试的课程记录了什么 - 但根据我的经验,我几乎无法回想起有必要的情况.再说一次,对于其他人来说,这可能是一个更紧迫的问题).
IMO通常单独记录器不用担心,因为它不包含与您正在测试的类相关的任何状态.也就是说,记录器的状态(及其可能的变化)对测试类的状态没有任何影响.因此,它不会使您的单元测试更加困难.
另一种方法是通过构造函数将记录器注入(几乎)应用程序中的每个类.为了接口的一致性,即使所讨论的类目前没有记录任何内容,也应该注入它 - 另一种选择是当你发现某个时候现在你需要从这个类中记录一些东西时,你需要一个记录器,因此你需要为DI添加一个构造函数参数,打破所有客户端代码.我不喜欢这两种选择,我觉得使用DI进行测井会使我的生活变得复杂,以符合理论规则,没有任何具体的好处.
所以我的底线是:一个几乎普遍使用的类,但不包含与你的app相关的状态,可以安全地实现为Singleton.
它主要是,但不是关于测试.Singltons很受欢迎,因为它很容易消耗它们,但单身人士有许多缺点.
DI让您轻松使用依赖类 - 只需将其放入构造函数args中,系统就可以为您提供 - 同时为您提供测试和构建灵活性.
大约唯一一次您应该使用 Singleton 而不是依赖注入的是 Singleton 表示不可变值,例如 List.Empty 等(假设不可变列表)。
对 Singleton 的直觉检查应该是“如果这是一个全局变量而不是 Singleton,我可以吗?” 如果没有,您正在使用单例模式来掩盖全局变量,并且应该考虑采用不同的方法。
| 归档时间: |
|
| 查看次数: |
38935 次 |
| 最近记录: |