依存性注入の反対を示す専門用語?


12

これは、純粋に技術的な質問というよりも、命名法(技術文書)です。私は、アプリケーションでの依存性注入の拡大を中心に、リファクタリングの提案を書いています(そして、それを自分に割り当てます)。Beanの自動配線にSpringを使用していますがMyClass obj = new MyClass(...)、を使用してBeanをインスタンス化するインスタンスがまだあります。私の提案では、エレガントな命名法を使用し、適切な用語でDIの反対のデザインパターンを参照したいと思います。

「密結合」は、DIの反意語として適切な用語ですか?


1
はい、カップリングは、他のクラスで明示的なクラス名を使用する動作と、結果のコードベースの状態の両方を表します。
キリアンフォス16

11
いいえ、密結合は結果のコードのプロパティのみを説明し、DIの反対ではありません。DIを使用しても、まったく異なる理由で密結合を維持できます。
Doc Brown


@EricKingが披露します。ところで+1。
-candied_orange

1
「依存関係の吸引」
-SeldomNeedy

回答:


30

いいえ。密結合は、依存性注入が処理する以上のものです。

依存性注入は、実装の決定を外部化します。これは切り離しに大いに役立ちますが、カップリングはこれ以上のものです。

依存性注入の良い反意語は、依存性のハードコーディングです。ビヘイビアーオブジェクト内で構築する(新しいファクトリーを使用するか、直接ファクトリーを使用する)場合、2つの異なる懸念事項をまとめてしまいます。サービスロケーターは分離に役立ちますが、ユーザーはサービスロケーター自体に結合されたままになります。

結合は、構造と動作を分離するだけではありません。クラスAからクラスBに特定の順序で呼び出す必要がある101個のメソッドがある場合、私は密結合しています。構造と動作がどれほど素晴らしく分離されていても構いません。

結合は、2つのオブジェクトの相互依存性の尺度です。他方に影響を与えずに一方を変更することを困難にすることに貢献するものはすべて、カップリングに貢献しています。依存性注入はこれに役立ちますが、これだけではありません。


はい、ハードコーディング(依存関係)は(実行時に)挿入するのではなく、まさに私が提案しようとしていたものです。
ドックブラウン

7
@DocBrown私は時々、この場所が高速であることをそれほど強調しないことを願っています。私はあなたがそれをどのように配置したか聞きたいです。
candied_orange

良い答え-依存性の注入はデカップリングを意味しません。そうでなければ信じることが悪い道を導く
Ant P

1
@CandiedOrangeたぶん、誰かが答えを一定期間非表示にしておくことをメタで提案するべきでしょう。そして/または、その投票はN何時間もパブリックビューから隠されます...または回答が選択されるまで。1つの回答がすでに10票を持ち、他の5つの回答が何も持っていない場合、は完全に客観的でないことを知っています!
svidgen

1
@svidgenは、「西で最も速い銃」をメタで検索します。この問題にはすでに長い歴史があります。
candied_orange

6

厳密に言えば、依存性注入は実際にはNOT依存性注入にのみ反対します。したがって、依存性注入ではない依存関係管理戦略にのみ反対します。

[望ましくない]カップリングは、厳密に直交する問題ではありませんが、どちらの方法でも発生するか、軽減される可能性があります。これらは両方とも以下に結合されDependencyClassます。

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructorDependencyClassこの場合、特定のものに結合されます。しかし、それらは両方とも結合されていDependencyClassます。本当の悪は、ここに存在する場合、必ずしもカップリングではありません。突然、独自の依存性を注入する必要があるDependencyLookupConstructor場合、変更するDependencyClass必要があります1

ただし、このコンストラクター/クラスはさらに疎結合です。

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

C#で作業している場合、上記は、呼び出されたときに何でもServiceLocator返すことができるようにします。完全なインターフェイス2に結合することなく、コンパイル時の署名検証のメリットを享受できます。GetMyDoer()do()DependencyLocatingConstructordo()

だから、あなたの毒を選んでください。

しかし、基本的に、依存性注入の具体的な「反対」がある場合、それは「依存性管理戦略」の領域の別のものになります。とりわけ、会話で次のいずれかを使用した場合、依存性注入ではないと認識します。

  • サービスロケーターパターン
  • 依存関係ロケーター/場所
  • オブジェクト/依存関係の直接構築
  • 非表示の依存関係
  • 「非依存性注入」

1.皮肉なことに、DIが上位レベルで解決する問題の一部は、下位レベルでDIを使用しすぎた結果です。私は不必要な複雑さを持つコードベースに取り組んでの喜び持っていたすべてのオーバーとしてその複雑さは、実際に助けた場所の一握りを収容した結果を...私は確かに悪いの暴露によってバイアスされています。

2.サービスの場所を使用すると、依存関係がどのように構築されているかについて大部分はわからないまま、呼び出しコードからの機能的役割によって同じタイプの異なる依存関係を簡単に指定できます。解決する必要がある場合UserIUser、さまざまな目的で、たとえば、Locator.GetAdministrator()対、またはその他のことを行う必要があるとしますLocator.GetAuthor()。私のコードは、サポートするインターフェイスを知らなくても、機能的に必要ものを尋ねることができます。


2
救いDependencyInjectedConstructor(DependencyClass dep)は、DependencyClassがインターフェースまたは抽象クラスになる可能性があることです。これが、C#コーダーがのようにインターフェイスプレフィックスを使用することを悲しくさせる理由IDependencyです。クライアントとして、この依存関係のことは本当に私のビジネスではありません。私がそれを構築しない限り、私が知る必要があるのはそれと話す方法だけです。それは他の誰かの問題です。
candied_orange

ポイントは、DIはまだあなたをそのインターフェースに結び付けており、それが抽象インターフェースであることをまったく必要としませんDependencyClass。構築/構成/ロケーションロジックが「どこか他の場所」に存在することだけが必要です。...まあ、そしてより適切に質問に、ポイントはDIが「密結合の反対」ではないということです:)
svidgen

実際に... C#であっても、DIは必然的にインターフェイスにあなたをつなぐと言うのは少し範囲外かもしれません。C#ではそれらを回避しましたが、dynamicパラメーターも受け入れることができるという印象を受けています。(ではなく、varパラメータ、メモリが提供する場合。)そうでは、C#でのDIと、私は考えて、私はどちらかのインターフェイスに対してコードを持っているか、私は完全にコンパイル時の検証を見合わせる必要があります。
svidgen

オブジェクトはインターフェースに結合されます。interfaceキーワードを使用するかどうか。それが適切なインターフェイスです。結合する必要があるすべて。必要なものは、実装の詳細と、不要な追加物です。interfaceキーワードを使用して、クライアントに「必要なのはこれだけです」と世界に伝えることにより、これを形式化できます。しかし、そうする必要はありません。一部の言語では、カモタイピングを行うことができます。
candied_orange

私たちが完全に意見の相違があるかどうかはわかりません。しかし、明確にするために...オブジェクトは内部で独自のインターフェイスに結合されています、はい。ただし、インターフェイス自体に明示的に名前が付けられている場合にのみ、インターフェイス自体が依存関係のカップリングを課します。C#では、ロケーターからオブジェクトを取得dynamicまたはvar取得することで、インターフェイスを無視し、そのクラスがインターフェイスを実装しているかどうかに関係なく、必要なクラスを使用できます。言い換えれば、A-> B <-Cがある場合、DIはAをCから切り離しますが、AとCの両方をBに連結する必要があり、DがそうであってもDの使用を防ぎます。do()IDoerdo()
svidgen

2

特定の広く受け入れられている業界用語があることは知りませんが、思い浮かぶ代替案には、内部インスタンス作成内部依存関係作成ローカル依存関係、またはローカルスコープ依存関係が含まれます。


2
私は好きですinstance creationが、それは十分に具体的ではありません。DIはインスタンスを作成しますが、アプリケーションレベルではなくコントローラーを使用します。多分internal instance creation
両生類

1

私は依存関係のカプセル化に行きます。これは、再度アクセスして離れるのではなく、依存関係がロックされていることを表しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.