单例模式还是非单例模式

9
我有一个正在运行的Windows服务。在这个服务中,我托管了一些服务(WCF)。 我需要一种“内存数据持有者”类。这个类的目的是在Windows服务运行期间保存非持久化数据。 这个类必须通过WCF服务访问。它们将一些值放入此类或从此类检索某些值。
我脑海中首先想到的是单例类。我认为这种模式非常适合这种情况。但后来我读到了一些帖子,说单例类并不是那么好。
那么,在这种情况下有没有其他选择?或者单例对这个问题来说可以吗?工厂方法呢?但是对象的引用在哪里找呢?
3个回答

15

单例设计模式应该被重新标记为反面模式,它是有害的,请不要使用。

更好的替代方案是使用依赖注入(DI)并注入一个类来保存你需要的非持久化数据。

许多人没有意识到WCF支持依赖注入(DI)模式,如构造函数注入,而且使用起来也不太麻烦。

如果你将注入的类作为长期存在的对象(通常称为单例生命周期样式,但不要与单例设计模式混淆),你可以在调用之间继续访问同一实例。

然而,无论你使用单例作为设计模式还是生命周期样式,你都必须准备好处理多线程问题。

这篇文章和许多其他文章中,描述了如何在WCF服务实现中注入依赖项,当它没有默认构造函数时。


你觉得单例模式为什么会被认为是邪恶的呢? - AJM
3
Stackoverflow知道:https://dev59.com/YXVC5IYBdhLWcg3w9GA9单例模式的问题在于它将状态全局化,这意味着任何代码都可以修改状态并且状态的变化可能会影响整个系统。此外,它使得代码更难以测试,因为测试需要重置状态并保证一个测试不会影响其他测试。最后,单例通常被用作一种简单方便的解决方案,但是在系统规模扩大时很容易出现问题。 - tanascius

6

我想知道为什么人们不喜欢单例模式,除非有人能告诉我一些好的理由,否则我很乐意在上述情况下使用它。

这是一个简单易懂且易于实现的模式,我认为保持简单对于6个月后您或其他人必须维护代码是一件好事。

编辑 通过进一步了解为什么一些人不喜欢单例模式,该问题提出了一些有用的替代方案:What's Alternative to Singleton。这解决了该模式的单元测试缺陷。

编辑2 我最终被说服单例可能并不好。http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html提出了一个很好的观点,即在维护方面,在API级别声明依赖关系可以使程序员更容易掌握依赖关系。


1
这里在SO上有一些好问题 - 你也可以谷歌搜索“单例被认为是有害的”,这将显示出有趣的讨论。 - tanascius
第二篇文章真的是一个很好理解的例子...我必须要收藏起来...不管怎样感谢和点赞。 - tanascius
我对第二个例子并不感到满意。这些问题可以通过在CreditCard构造函数中验证初始化和触发断言来解决。 - lorean

1
为什么你需要一个单例模式来实现这个?
你真的有必要将这个类的实例限制为一个吗?如果不是,就不要使用单例模式 - 你不需要它,而且它只会给你的类增加复杂性。

但是我应该在哪里存储创建对象的实例引用呢?我的意思是,当创建对象的方法运行超出范围时,对象将会丢失。 - user137348

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接