依存性注入:プラグイン
6616 ワード
ステージの設定
依存性注入は空想的な用語です.それは威圧的に聞こえる.このポストの目的は、どのような依存性の注入であるか、それをどのように使うか、そしてなぜそれが有益であるかを説明することです.説明するために、コンサートでギターを演奏することについて話しましょうRubyConf 2020 ルビーの話Coverage モジュールです.
サウンドチェック
バンドのギタリストは、ライブコンサートをするときアンプを使います.
class Guitar
def initialize
@amplifier = Amplifier.new
end
end
ギターが鳴っているとき、音はアンプで旅行します.class Guitar
def strum(chord)
chord.phrasing.each do |string_sound|
@amplifier.play(string_sound.amp_value)
end
end
end
このセットアップで素晴らしいショーをプレイすることができます!あなたのギターはそれが定義するアンプを使用し、すべてがよくあります.…まで音の壁
いくつかのギタリスト実験ギアで-多く.別のアンプは、異なる音を出すつもりです.しかし、我々はそれが非常に難しい私たちのギターを別のアンプに接続されるようにした.
たった今、ギターから音を再生するためにアンプクラスに対する我々の依存は、ハードでコード化されます
Guitar
クラス.初期化子は、Amplifier
クラス.我々がギターをプラグに入れたいならば
LouderAmplifier
, 我々は、我々の変化なしでそれをすることができませんGuitar
クラス.すべての異なるアンプは、我々の変化を必要としますGuitar
クラス.プラグアンドプレイ
我々は新しいギターを作るときにギターで使用されるアンプで渡す代わりに、この制限を解決することができます.
class Guitar
def initialize(amplifier)
@amplifier = amplifier
end
end
この小さな変化でGuitar
に応答するすべてのアンプで動作することができますplay
メソッド.に結合されていないAmplifier
クラスでは、Guitar
クラスは、代わりにこの共同クラスで明示的にパスします.これは特に依存性注入の形式ですConstructor Injection .音響工学
依存関係の注入の例を見てみましょう.
柔軟性
これは上の例で説明した動機です.ハードコード依存性をクラスの実装の詳細として削除することによって、クラス内で使用するメソッドに応答する限り、依存関係を使用することができます.我々のために、これはギターが彼らが好きであるどんなアンプでも使うことができることを意味します;ギタリストは最初にギターを買ったときのアンプに限らない.
テスト
テストは、この柔軟性の値が評価されることができる最初の状況であるかもしれません.テストはあなたの実装の最初の消費者です、そして、彼らがあなたに与える潜在的なフィードバックを聞くことは重要です.クラスまたはメソッドがテストするのが難しい場合、それは非常に可能性があります-または、少なくとも理解するために複雑に使用されます.
実際には、テストの難しさ
Guitar
class は、増幅器を注入するという決定に導きました.それはAmplifier
class は本質的にラッパですSonic Pi . ソニックパイは、“コードベースの音楽の作成とパフォーマンスツール”として自分自身を説明するので、このアンプでギターを演奏実際にあなたのコンピュータ上のサウンドを再生します.としてエキサイティングなので、私はちょうど私のテストを実行するソニックパイを実行していない.そして、たとえ私がしたとしても、私がテストを実行するたびに、それが生成する音を聞く必要はありません.そして、私はテストのために別々のアンプをつくりました:A
PracticeAmplifier
. あのアンプは何をするのですか.Absolutely nothing ! そして、それは私の単体テストに最適です.彼らはギターを演奏するときにアンプが作る音に関係していない.彼らは、中にある論理を行使することに興味がありますGuitar
クラスのみ.より一般的に、あなたのクラスは、API呼び出しをするか、ファイルI/Oを実行するもう一つのクラスと協力しているかもしれません.代わりに、これらのことをしない別のクラスで渡すことができます、あなたのテストで迅速かつ適切なフィードバックを提供する.
複雑性同定
システムの責任は時間とともに成長する傾向がある.これは、アプリケーション全体に対してのみではなく、個々のクラスやメソッドに対して異なるコンポーネントに依存します.機能は、クラスに追加され続けているように、より多くの協力者に追加する必要があります.これらの変更の各々が時間とともに断片的になされるならば、クラスを連結する方法が他のクラスにどのように結合するかだけでなく、どのように多くのクラスがそれに連結されるかについて、後退させて、理解するのは難しくありえます.
依存関係を注入すると、明示的にこのクラスが依存しているもの、およびどのように多くのことがわかります.コンストラクタまたはメソッドに渡す必要があるもののリストとして、新しい機能をサポートするために成長すると、クラスやメソッド内の複雑さを測定するためのプロキシとして機能することができます.これは、異なる抽象化またはリファクタリングを実装するためにより自然な圧力をかけるかもしれません.
ロックオン
Rubyの固有の柔軟性は依存性注入をより少ないツールに到達させることができますtesting あなたが最初にその痛みに気づくとき、私たちの処分で依存関係をテストする相互作用をより簡単にすることを与えられます.
依存性インジェクションは、しばしばあなたがヘビー級を必要とするという仮定を運んでいる不吉な用語ですframework 実装する.ただし、初期化子(コンストラクタ)または個々のメソッドに引数としてオブジェクト内で渡すことができる場合-おめでとう、あなたは依存を注入した!
依存関係の注入を使用すると、より密に結合されたコードにつながることがあります.これは、他のユーザーとの協調の柔軟性を考慮し、テストの負担を軽減し、クラスが現在のデザインを再考する必要がある点まで成長しているときにより明確になります.
我々のシリーズの次のポストは、ルビーのアヒルタイピングを使用して説明します.
This post originally published on The Gnar Company blog.
Reference
この問題について(依存性注入:プラグイン), 我々は、より多くの情報をここで見つけました https://dev.to/thegnarco/dependency-injection-plug-in-cmiテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol