辛格尔顿工厂的替代品
本文关键字:替代品 工厂 | 更新日期: 2023-09-27 18:27:54
我正在围绕一个我无法控制的类库编写一个包装器。在这个库中有一个类(让我们称之为Target
),我想确保它只实例化一次,但它本身并不是一个单例。我想使用Singleton Factory模式,如下所示:
internal sealed class SingletonFactory
{
private static readonly SingletonFactory manager = new SingletonFactory();
private readonly Target target;
private static SingletonFactory() { }
private SingletonFactory()
{
target = new Target();
target.Init("foo");
}
internal static SingletonFactory Instance
{
get { return manager; }
}
internal Target Target
{
get { return target; }
}
}
然后我可以做:
var targetInstance = SingletonFactory.Instance.Target;
然后我想通过使工厂完全静态来简化这一点:
internal static class StaticFactory
{
private static readonly Target target;
private static StaticFactory()
{
target = new Target();
target.Init("foo");
}
internal static Target Target
{
get { return target; }
}
}
并且对目标实例的访问变为:
var targetInstance StaticFactory.Target;
我确信这个StaticFactory
是线程安全的,并且提供了对目标类的单个实例的全局访问。这有什么我没有想到的问题吗?
我不确定你的构造函数是否真的是线程安全的,因为从技术上讲,它可以同时从不同的线程访问。您可以锁定private static readonly object Lock = new object();
以在那里强制线程安全。
如果我们谈论的是C#4,您可能还想在这里查看Lazy<T>
http://msdn.microsoft.com/de-de/library/ee792409.aspx.它支持线程安全创建模式LazyThreadSafetyMode
,使您能够在安全性和性能之间找到折衷方案。
旁注:最后,不使用静态类可能是更好的设计决策,因为您可以防止架构上不可见的依赖关系,并获得交换实现的能力。使用抽象工厂解决了这一问题(也提供了良好的单元测试体验)。
其实也是一样,只是你的静态构造函数上有private关键字,这是不允许的。
internal static class StaticFactory
{
public static Target Target = new Target();
static StaticFactory()
{
Target.Init("foo");
}
}
你可以得到幻想,并将其全部推入懒惰:
public static Lazy<Target> Target =
new Lazy<Target>(() => { var t = new Target(); t.Init(""); return t; });
您还可以建立一个facade,它将为您提供与Target相同的语义,但将其保留为一个实例。它还为您提供了在何时何地初始化Target对象的空间。
public class TargetFacade
{
private static Target _target = new Target();
static StaticFactory()
{
_target.Init("foo");
}
//Wrap Target's methods here.
public int Score { get { return _target.Score } };
}