私はたくさんの(抽象的な)ファクトリを持っており、それらは通常シングルトンとして実装されています。
通常、これらのファクトリを使用したり知ったりすることにまったく関係のないレイヤーを通過させなくて済むという利便性のためです。
ほとんどの場合、起動時に、おそらく何らかの構成を通じて、残りのコードプログラムがどのファクトリー実装を実行するかを決定するだけで済みます。
例えば次のようになります
abstract class ColumnCalculationFactory {
private static ColumnCalculationFactory factory;
public static void SetFactory(ColumnCalculationFactory f) {
factory = f;
}
public static void Factory() {
return factory;
}
public IPercentCalculation CreatePercentCalculation();
public IAverageCalculation CreateAverageCalculation();
//....
}
何かが臭いがするが、それが何なのかはわからない。シングルトンというよりは、隠されたグローバルなのかもしれない。本当に本当にしなければならないColumnCalculations を作成するファクトリは 1 つだけですが、私のプログラムではそれ以上は必要ありません。
これはベストプラクティスと考えられますか? これらを (半) グローバル AppContext クラスに詰め込むべきでしょうか? 他に何かありますか (ちなみに、まだ大きな IoC コンテナーや spring.net に切り替える準備ができていません)?
ベストアンサー1
それは、あなたが何をしているか、そしてあなたのアプリケーションの範囲によって大きく異なります。それがかなり小さなアプリケーションであり、これ以上大きくなることはないのであれば、現在のアプローチで十分でしょう。これらのことに関して普遍的な「ベスト」プラクティスはありません。ステートレスなリーフ メソッドや一方向の呼び出し (例: ログ記録) 以外の用途にシングルトンを使用することはお勧めしませんが、シングルトンであるという理由だけでそれをすぐに却下するのは必ずしも正しいことではありません。
些細なコードやプロトタイプ コード以外では、コンストラクター インジェクションによる制御の反転を明示的に使用することを個人的には好みます。これは、すべての依存関係が考慮され、「驚き」が起こらないことを意味します。コンパイラーは、B なしで A をインスタンス化したり、C なしで B をインスタンス化したりすることを許可しません。シングルトンはこれらの関係をすぐに埋めます。つまり、B なしで A をインスタンス化したり、C なしで B をインスタンス化したりできます。A から B への呼び出しが発生すると、null 参照例外が発生します。
これは、実行時の失敗を遡って繰り返し作業する必要があるため、テスト時に特に厄介です。コードをテストするときは、他のプログラマーと同じように API を使用するため、このアプローチの設計上の問題が明らかになります。コンストラクター インジェクションにより、このような事態は発生しません。依存関係はすべて事前に記述されます。コンストラクター インジェクションの欠点は、オブジェクト グラフの構成が複雑になることです。これは、IoC コンテナーの使用によって軽減されます。
私が言おうとしているのは、何らかのコンテキスト オブジェクトとレジストリ パターンの使用を検討する段階に達した場合は、IoC コンテナーも検討したほうがよいということです。Autofac のような確立された無料製品を使用できる場合、独自の mutt バージョンを作成する手間をかけるのはおそらく時間の無駄です。