0

制御できないクラスライブラリのラッパーを作成しています。Targetこのライブラリには、 1回だけインスタンス化されることを確認したいクラス(これを呼びましょう)がありますが、それ自体はシングルトンではありません。私は次のように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");
    }
}

あなたは空想を得て、それをすべて怠惰に押し込むことができます:

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

技術的には同時に異なるスレッドからアクセスできるため、コンストラクターが本当にスレッドセーフであるかどうかはわかりません。をロックして、private 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 に答える