单身实际上什么时候比静态类更容易或更好?在我看来,创建单身只是额外的努力,实际上并不需要,但我确信有一个很好的理由。否则,显然不会使用它们。
答案 0 :(得分:27)
在静态类中优先考虑单例的一个很好的理由(假设你没有更好的模式;)),将一个单例实例与另一个实例交换。
例如,如果我有这样的日志记录类:
public static class Logger {
public static void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Log("DoSomething called");
}
}
它工作得很好,但是如果Logger将数据写入数据库或将输出写入控制台会怎样。如果你正在编写测试,你可能不希望所有这些副作用 - 但由于log方法是静态的,除了以外你不能做任何事情。
好的,所以我想热插拔我的Log方法进行测试。 Go go gadget singleton!
public class Logger {
private static Logger _instance;
public static Logger Instance
{
get
{
if (_instance == null)
_instance = new Logger();
return _instance;
}
set { _instance = value; }
}
protected Logger() { }
public virtual void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Instance.Log("DoSomething called");
}
}
因此,您可以使用空TestLogger : Logger
方法定义Log
,然后将测试记录器的实例设置为单例实例以进行测试。普雷斯托!您可以在不影响客户端代码的情况下热切换您的记录器实现以进行测试或生产。
答案 1 :(得分:10)
单身人士往往更喜欢全球变量,因为:
修改强>
单身人士的一个很酷的用途是,当与工厂方法结合使用时,可以用来创建Flyweight pattern。这是当你创建一个新对象时,Factory(而不是创建一个新对象)首先检查是否已经创建了该对象的单例,如果是,它只返回该对象,如果没有,它会创建一个新的单例并返回,跟踪它创建的单身人士。 Flyweights的工作原因是单身人士的不变性。
答案 2 :(得分:7)
public interface IFooProvider {
Bar FooBar();
}
public static class Foo {
public static readonly IFooProvider FooProvider { get; set; }
public Bar FooBar() { return FooProvider.FooBar(); }
}
然后我确保在我的init方法中将提供程序设置在某处。如果您想通过在类初始化时设置默认提供程序,则可以轻松添加延迟初始化。最重要的是,它允许您在保持使用静态类的美感的同时改变行为。
答案 3 :(得分:4)
尽管恕我直言,单身人士模式是一种过度使用的模式,但它确实有时会带来好处,例如:
答案 4 :(得分:3)
在许多语言中,静态类缺少有用的功能,如继承(以及更普遍的多态)。
答案 5 :(得分:2)
Singletons保留了传统的类方法,并且不要求您在任何地方使用static关键字。它们最初可能要求更高,但会大大简化程序的体系结构。与静态类不同,我们可以使用单例作为参数或对象。
此外,您可以像其他任何类一样使用带有接口的单例。
答案 6 :(得分:2)