重要状态的对象最佳设计模式 - 单例模式还是静态模式?

3
更具体地说,在实现依赖注入的应用程序中,对于状态很重要的类,最好的方法是什么。
比如说,我需要访问处于特定状态的对象。例如,这个对象可能已经在不同的线程中初始化,或者是由我无法控制的进程初始化。
一个已经存在于.NET中的这样的对象的很好例子就是HttpContext。
在这种情况下,Microsoft决定采用静态方法,所以我只需要说:
var currentObj = HttpContext.Current;

这使我能够获得一个特定的对象实例,而不必担心它来自哪里。
静态方法的问题在于它与依赖注入的结合不是很好。
另一种选择是在您的IoC容器中将某个类配置为单例。这意味着您可以注入它,并且根据当前的IoC容器配置,它将是该类的正确实例。
但是,这种方法的缺点是对象的有状态重要性不再在代码中明确,通过查看代码并不明显。使用Static类访问和实例化更清晰地表明了状态的重要性。也许这并不重要。
那么,有没有一种模式可以帮助我?
背景:我正在开发一个具有许多执行IO操作的类实例的应用程序。它们存在于自己的线程中。
我想通过Web界面(控制器)与这些对象(后台任务)进行交互。我想能够询问它们并操作它们等。
更新:抱歉,我觉得我使用“有状态”的术语有点误导人。让我解释一下:
1. “状态”可能是错误的词。我的意思是与对象通信,我对其生命周期没有控制权。
2. 当我谈论静态类时,使用“有状态”是有趣的。这就是为什么我举了HttpContext的例子,因为它确实是这样做的。Current属性为您提供一个非常特定的实例,而不是任何新实例。
3. 当我说静态方法与DI不兼容时,我的意思是,您无法注入静态类。是的,我可以创建一个包装器,但我只是将问题推到其他地方,不是吗?
4. 我应该更清楚地定义Singleton。我指的是IoC容器中定义的单例生命周期。

"静态方法的问题在于它与依赖注入不太兼容。" - 你尝试过什么了吗?似乎你可以考虑使用池而不是单例。 - Kangkan
“对象的状态重要性在代码中不再明确”是什么意思?你的问题似乎太抽象了,无法回答。难道不是所有非平凡对象都有状态吗?对我来说,讽刺的是你将“有状态”的术语应用于静态方法。 - JohnOpincar
一个 Singleton 的 get 访问器本身就是一个静态属性(或者如果你喜欢的话,是一个方法),不是吗?因此这不仅仅是关于静态 vs. Singleton 的问题,更多的是关于你的方法... - Mark Ursino
2
@Mark:假设他可以在DI框架中将该项标记为单例,这样每个人都会返回相同的实例。因此,并不一定涉及静态属性。 - JohnOpincar
@JohnOpincar:“假设他可以在DI框架中将该项标记为单例,这样每个人都会返回相同的实例”- John说得完全正确,谢谢。 - andy
3个回答

3

我总是更喜欢Singleton模式而不是静态模式。实际上,我几乎从不在自己的类中使用静态。


很酷,谢谢约翰。我想我问这个问题是想看看是否有什么更好的第三个选项。我想关键是选择一个IoC容器控制器单例。干杯 - andy

1

真正的单例和静态类都很难编写自动化测试。你是指在运行时查找单个实例吗?这对我来说很有意义,但我不知道在C#中使用哪种构造。在Java中的类比是JNDI。


1

都可以,或者都不可以。假设有状态的依赖是线程安全的,更好的方法是在该依赖周围至少构建一个基本的抽象层,然后将该抽象层注入到您的类中。这时单例与静态的区别就变得不那么重要了。


你不觉得这样做只是把问题转移到另一个类中吗? - andy
不是真的。你的类具有构造函数依赖性,不太关心依赖项来自何方。可以根据需要轻松使用实例类,或使用IoC封装单例或静态引用。 - Wyatt Barnett

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