Jou*_*aas 39 singleton static design-patterns class
单身实际上何时比静态类更容易或更好?在我看来,创建单身只是额外的努力,实际上并不需要,但我确信有一个很好的理由.否则,显然不会使用它们.
Jul*_*iet 28
在静态类中优先使用单例的一个很好的理由(假设您没有更好的模式可供使用;)),将一个单例实例与另一个实例进行交换.
例如,如果我有一个这样的日志类:
public static class Logger {
public static void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Log("DoSomething called");
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好,但是如果Logger将数据写入数据库或将输出写入控制台会怎样.如果您正在编写测试,您可能不希望所有这些副作用 - 但由于日志方法是静态的,除了以外您不能做任何事情.
好的,所以我想热插拔我的Log方法进行测试.去小工具单身!
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");
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以TestLogger : Logger使用空Log方法定义a ,然后将测试记录器的实例设置为单例实例以进行测试.普雷斯托!您可以在不影响客户端代码的情况下热切换您的记录器实现以进行测试或生产.
Rya*_*yes 10
单身人士往往更喜欢全局变量,因为:
编辑:
单例的一个很酷的用途是,当与工厂方法结合使用时,可以用于创建Flyweight模式.这是当你创建一个新对象时,Factory(而不是创建一个新对象)首先检查是否已经创建了该对象的单例,如果是,它只返回该对象,如果没有,它会创建一个新的单例并返回,跟踪它创造的单身人士.Flyweights的工作原因是单身人士的不变性.
小智 7
单身人士对我来说似乎总是多余.我更喜欢静态类,如果我需要不同的行为,我将它与依赖注入和提供者结合起来.我不知道这是什么模式,或者它是否有名称,但它通常是这样的:
public interface IFooProvider {
Bar FooBar();
}
public static class Foo {
public static readonly IFooProvider FooProvider { get; set; }
public Bar FooBar() { return FooProvider.FooBar(); }
}
Run Code Online (Sandbox Code Playgroud)
然后我确保在我的init方法中的某个地方设置提供程序.如果您想通过在类初始化时设置默认提供程序,则可以轻松添加延迟初始化.最重要的是,它允许您在保持使用静态类的美感的同时改变行为.
即使恕我直言,单例模式是一种过度使用的模式,它有时也会带来好处,例如: