0

静的initメソッドを介して静的フィールドを初期化し、その後メソッドが二度と呼び出されないようにする最良の方法は何ですか? (プログラムの存続期間中に 1 回のみ)

これは私が現在考えていることの例です。私には非常に単純に思えますが、これに対処する同様のパターンの例は見つかりませんでした:

class Entity
{
    static Manager manager;
    static bool isInitialized;

    public static void Initialize(Manager manager)
    {
        if (isInitialized)
            throw Exception("Class Entity already initialized."
                 + "Do not call Entity.Initialize() twice.");
        isInitialized = true;
        Entity.manager = manager;

    }
}
4

6 に答える 6

6

静的 init メソッドを介して静的フィールドを初期化し、その後メソッドが二度と呼び出されないようにする最良の方法は何ですか?

あなたは本当にこれをしなければなりませんか?Managerのインスタンスを作成し、依存性注入によってそれに依存するコードで使用できるようにしたくないのはなぜですか? これにより、コードがよりクリーンになります。

  • さまざまな初期化パスでテストできるようにします
  • 「悪い」重複初期化をチェックする必要はありません
  • このクラスの単一の初期化ポイントを指定するために、呼び出しコードを構造化する必要はありません。(もちろん、IoC コンテナーについても同様のことを行う必要があるかもしれません...)
  • それに依存するコードをよりテストしやすくすることもできます
  • 依存するコードはManager、その依存関係をより明確な方法で表現します

これはアンチパターンであるため、同様の例が見つからなかったと思います。

現在のアプローチを採用する場合、スレッドセーフにすることも本当に試してください...

于 2012-05-30T18:47:09.883 に答える
1

考えすぎないでください。そのパターンがうまくいく場合は、それを使用してください。常に「正しい」答えがあるとは限りません。また、厳格なパターンや慣習に固執するためだけに固執しようとすることも、良い考えではありません。私見では。

于 2012-05-30T18:50:06.247 に答える
1

明白なことを述べて申し訳ありませんが、オブジェクト初期化子または静的コンストラクターを使用できます。それ以外に、メソッドを呼び出すことはできません。真剣に。とにかく誰かがinitializeというメソッドを呼び出すのはなぜですか。

あなたができることはこれです。この属性を使用して、IntelliSenseなどからメソッドを非表示にすることができます。ドロップダウンが乱雑になるのを防ぎます

于 2012-05-30T18:50:58.693 に答える
0

実装はスレッドセーフではありませんが、それ以外の点では合理的です。マルチスレッド環境での使用を目的としている場合は、ロックを追加します。

サンプルでは、​​未解決の質問は、複数の呼び出し元(おそらく複数のスレッドから)が異なるパラメーターを使用して初期化メソッドを呼び出した場合にどうなるかです。これがパターンを異常なものにし、明白な静的コンストラクターまたはオブジェクト初期化子を使用できないようにします。

于 2012-05-30T18:51:09.543 に答える
0

静的コンストラクターだけを使用することはできませんか?

もちろん、このコンストラクターがいつ呼び出されるかを制御することはできませんが、これが要件であるかどうかはわかりません。

http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx

于 2012-05-30T18:51:39.067 に答える
0

Manager変数の特定の機能のみを公開するために、パラメーター付きのシングルトンパターンを使用することをお勧めします。

class Entity
{
    private Manager _manager = null;

    public Manager manager
    {
        get
        {
            return _manager;
        }
        set
        {
            if (manager == null)
            {
                _manager = value;
            }
        }
    }
    /* rest of class */
}

これで、マネージャーオブジェクトを任意の変数として使用できますが、セットを繰り返しても値は変更されません。

this.manager = new Manager(0); // sets the manager
this.manager = new Manager(1); // does nothing

ここで、コンストラクターのどこかまたはリセット関数でパターンを完成させるために、

this._manager = null;
于 2012-05-30T18:54:29.440 に答える