3

同じインターフェイスを実装するアルゴリズム クラスが多数あります。別の「ファクトリ」クラスには、構成パラメーターを介して正しいアルゴリズム クラスをインスタンス化し、そのインスタンスで start メソッドを呼び出す責任があります。

アルゴリズム クラスのコンストラクタ (またはその他のインスタンス作成メカニズム) の可視性をファクトリ クラスのみに制限したいと思います。

どうすればこれを解決できますか? 私が考えることができる唯一のクリーンな解決策は、これらのクラスを別の .dll に移動し、アルゴリズム クラスをプライベートに変更することですが、それは私が今やりたいことではありません。

4

2 に答える 2

3

これはあなたが聞きたがる答えではありませんが、しないでください。

そのコンストラクターをprivate/internal/protected作成すると、アルゴリズムのテストが難しくなり、API のコンシューマーがファクトリを使用する代わりに独自の実装を手動で選択することもできなくなります。

コンストラクターを公開したままにして、必要なすべての依存関係がコンストラクターで宣言されていることを確認してください。コンストラクターのさまざまな修飾子に関する私の見解は次のとおりです。

  • public- 誰もがコンストラクターにアクセスでき、クラスをテストできます -これは良いことです。
  • protected- サブクラスはコンストラクターにアクセスできます。これは問題ありませんが、実際には抽象クラスおよび/またはコンストラクターの連鎖にのみ使用されます。
  • internalInternalsVisibleTo- コンストラクターの使用を(フレンド) アセンブリに制限しています。これは、アセンブリ内の誰でも通常どおりに構築できることを意味しますが、他のアセンブリはファクトリを明示的に使用するかInternalsVisibleTo強制に使用する必要があり、それによってアルゴリズムをファクトリに結合します。
  • private- デフォルトのコンストラクターを非表示にする場合 (ただし、少なくとも 1 つの引数を使用してコンストラクターを作成する場合はこれを行う必要はありません)、または連鎖可能なコンストラクターのみを作成する場合に便利です。

TL;DR -コンストラクター internalを作成しないことをお勧めします。そうすることで、クラスを作成することもできます internal(クラスではなく、インターフェイスによってアルゴリズムを参照していますよね?)

別の解決策は、クラスの実装を作成し、privateそれらを Factory 内にネストすることです。それらすべてに共通のインターフェースを実装させ(すでに行っているはずです)、そのインターフェースをアプリケーションの残りの部分に公開します。それでも、テストが困難になるという問題は回避できません。

于 2014-09-11T08:26:29.673 に答える
2

たぶん、次のサンプルで満足するでしょう (はい、どのリフレクションが通常使用されるべきでないかはわかっています...)

public class Algorithm
{
    private Algorithm()
    {
    }

    public void SomeMethod()
    {
    }
}

public static class Factory
{
    public static Algorithm Create()
    {
        var constructor = typeof(Algorithm).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null);
        return (Algorithm)constructor.Invoke(null);
    }
}

ここでは、新しいアルゴリズムではなく、Factory.Create を介してアルゴリズムのインスタンスを作成できます。

于 2014-09-11T08:24:24.970 に答える