0

私はビジネス層を持っていますが、そのクラスは 1 つだけが外の世界に見えるようにする必要があります。そのため、そのクラスを除くすべてのクラスを internal としてマークしました。そのクラスにはインスタンス化する内部クラスが必要なので、他のクラスをパブリックとしてマークする必要があり、他のクラスは他のクラスに依存するなどです。最終的に、私の内部クラスのほとんどすべてが公開されます。

そのようなシナリオをどのように処理しますか?

また、現在、外の世界に公開されているクラスは 1 つだけですが、将来は 2 つまたは 3 つになる可能性があるため、3 つのファサードが必要になるということですか?

ありがとう

4

4 に答える 4

2

多くの調査を行った後、依存性注入の初心者に役立つように、調査結果を書いています。


私の現在の設計と依存性注入に関する誤解:

最初のアプローチとそれに関連する問題:

私のビジネス層は、ビジネス層の外側でアプリケーション エントリ ポイントの近くにある必要があるため、その中にコンポジション ルートを持っていました。コンポジションルートでは、私は基本的に、Mark Seemann による Poor Man's DIと呼ばれる大きな工場を持っていました。私のアプリケーションの開始点では、このファクトリ クラスのインスタンスを作成し、次に、外部から見える唯一の (意図した) クラスを作成していました。この決定は、すべての依存関係は置き換え可能であるべきだというLiskov の原則に明らかに違反しています。私はモジュール設計を行っていましたが、以前のアプローチは密接に結合されていたため、コードのクリーンさとコードの保守性がいくらかしかなかったにもかかわらず、それ以上のメリットを得ることができませんでした。

より良いアプローチは次のとおりです。

Facio Ratio が提供する非常に役立つリンク

コンポジション ルートはアプリケーション ルートの近くに配置する必要があり、すべての依存関係クラスを公開する必要があり、最初はこれが問題でした。それらを公開するために、私は低結合を導入し、Liskov の優れた置換に従っています。

于 2013-08-31T13:45:58.407 に答える
0

解決策が 3 つありますが、本当に良いものはありません。何らかの方法でそれらを組み合わせたいと思うかもしれません。しかし...

最初に、いくつかの単純なパラメーター (おそらく数値) をコンストラクターに入れます。これにより、呼び出し元が何をしたいのかを伝えることができ、新しいパブリック クラス インスタンスが内部クラス オブジェクトを取得する (自己注入する) ために使用できるようになります。(ここでも、情報を伝達するためだけに使用される特別なパブリック クラス/インターフェイスを使用できます。) これは扱いにくく制限されたインターフェイスになりますが、カプセル化には最適です。呼び出し元が複雑な注入可能なオブジェクトを構築するためにいくつかの簡単なパラメーターを追加することを好む場合、これはうまくいくかもしれません。(必要な、または必要な唯一のオプションが「読み取り専用」と「編集可能」である場合に、メソッドがこれまで聞いたことのないクラスの 5 つのオブジェクトを必要とする場合、それは常にドラッグです。)

次に、内部クラスを公開することができます。現在、発信者は計り知れない力を持ち、何でもできます。これは、呼び出し元のコードが本当にシステムの心臓部である場合は良いことですが、そのコードを完全に信頼していない場合や、呼び出し元がうるさい詳細​​に煩わされたくない場合は悪いことです。

第 3 に、一部のクラスを呼び出し元のコードからアセンブリにプルできる場合があります。本当に運が良ければ、呼び出しを行うクラスが内部でうまく機能する可能性があります (この問題を 1 レベル上に再導入しないことを願っています)。

コメントへの対応:

私が理解しているように、ビジネス層のパブリック クラスでメソッドを呼び出すサービスがあります。呼び出しを行うには、ビジネス層の他のクラスのオブジェクトが必要です。これらの他のクラスは内部であり、内部であるべきです。たとえば、GetAverage というメソッドを呼び出して、(内部) クラス RoundingPolicy のインスタンスを渡し、丸め方を認識できるようにします。私の最初の答えは、クラスの代わりに整数値を使用する必要があるということです。ROUND_UP、ROUND_DOWN、NEAREST_INTEGER などの定数値です。GetAverage はこの数値を使用して、ビジネス層内に適切な RoundingPolicy インスタンスを生成し、RoundingPolicy を内部に保持します。

私の最初の答えは、私が提案しているものです。ただし、サービスにかなり原始的なインターフェイスを提供するため、2番目の2つの回答は代替案を示唆しています.

2 番目の答えは、実際に回避しようとしているものです。私の考えでは、これらすべての内部クラスサービスに必要な場合、問題を回避する方法はなかったのではないでしょうか。上記の例では、サービスが 30 行のコードを使用して適切な RoundingPolicy インスタンスを作成してから渡している場合、数個の整数パラメーターだけでは問題を解決できません。全体のデザインをよく考える必要があります。

3 番目の答えは絶望的な希望ですが、呼び出し元のコードが、ビジネス レイヤー内で同じように簡単に実行できる作業を実行していることに気付くかもしれません。これは実際には私の最初の答えに似ています。ただし、ここでは、インターフェイスがよりエレガントになる可能性があります。私の最初の答えは、サービスができることを制限します。この回答は、とにかくサービスがあまりやりたくないことを示唆しています。常に 1 つの同一の RoundingPolicy インスタンスを使用するため、パラメーターを渡す必要さえありません。

私はあなたの質問を完全には理解していないかもしれませんが、あなたが使用できるアイデアがどこかにあることを願っています.

さらに: 4番目の回答:

これは私の最初の回答の一部のようなものだと考えましたが、よく考えて、明示的に述べるべきだと思います。

呼び出しを行っているクラスにインターフェイスが必要だとは思いませんが、サービスに公開したくないすべてのクラスのインターフェイスを作成できます。たとえば、IRoundingPolicy。これらのインターフェイスの実際のインスタンスを取得するには、何らかの方法が必要です。これは機能new IRoundingPolicy()しないためです。これで、サービスは、非表示にしようとしていたクラスのすべての複雑さにさらされますが (下側)、クラスの内部は表示されません(上側)。サービスが何を処理するかを正確に制御できます。元のクラスはカプセル化されたままです。これはおそらく私の2番目の答えの実行可能なバージョンになります。これは、サービスが最初の回答よりも複雑なオプションを必要とする 1 つまたは 2 つの場所で役立つ可能性があります。

于 2013-07-19T20:16:53.287 に答える