0

我正在围绕一个我无法控制的类库编写一个包装器。在这个库中有一个类(我们称之为它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是线程安全的,并提供对目标类的单个实例的全局访问。这有什么我没有想到的问题吗?

4

2 回答 2

1

真的一样,除了你的静态构造函数上有 private 关键字,这是不允许的。

internal static class StaticFactory
{
    public static Target Target = new Target();

    static StaticFactory()
    {
       Target.Init("foo");
    }
}

你可以变得花哨,然后把它全部塞进一个 Lazy 中:

public static Lazy<Target> Target =
      new Lazy<Target>(() => { var t = new Target(); t.Init(""); return t; });

您还可以建立一个外观,它会为您提供与 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 } }; 
}
于 2012-03-16T05:05:06.477 回答
1

我不确定您的构造函数是否真的是线程安全的,因为从技术上讲,它可以同时从不同的线程访问。您可以锁定 aprivate static readonly object Lock = new object();以在那里强制执行线程安全。

如果我们谈论的是 C# 4,您可能还想看看Lazy<T>这里http://msdn.microsoft.com/de-de/library/ee792409.aspx。它支持线程安全的创建模式LazyThreadSafetyMode,允许您在安全性和性能之间找到折衷。

旁注:最后,不使用静态可能是更好的设计决策,因为您可以防止架构上不可见的依赖关系并获得交换实现的能力。使用抽象工厂解决了这个问题(并且还提供了很好的单元测试体验)。

于 2012-03-16T05:05:44.910 回答