依存関係の注入により、依存関係と依存型の結合が軽減されるため、依存型の実装を変更するときに、依存型の実装を変更する必要はありません。同時に、依存関係の注入により、より便利になります。依存型のテストに使用 「モッキング オブジェクト」は、元の依存型を置き換えて、依存オブジェクトの独立した単体テストの目的を達成します。
0. はじめに
ソフトウェア エンジニアリングの分野では、依存関係の挿入 (Dependency Injection) を使用して実装が行われます。制御フィードバック 制御の反転の最も一般的な方法の 1 つ。この記事では主に、依存関係注入の原理と一般的な実装方法を紹介し、適用可能なシナリオとこの新しい設計パターンの利点に焦点を当てます。
1. 依存関係の注入が必要な理由は何ですか?
制御の反転は切り離しに使用されます。誰が誰から切り離されるのか?これは、依存性注入について初めて学んだときに私が抱いた最初の疑問でした。
以下では、この問題を説明するために、Martin Flower がインジェクションを説明するときに使用したコードの一部を引用します。
public class MovieLister { private MovieFinder finder; public MovieLister() { finder = new MovieFinderImpl(); } public Movie[] moviesDirectedBy(String arg) { List allMovies = finder.findAll(); for (Iterator it = allMovies.iterator(); it.hasNext();) { Movie movie = (Movie) it.next(); if (!movie.getDirector().equals(arg)) it.remove(); } return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]); } ... }
public interface MovieFinder { List findAll(); }
必要な映画リストを提供するために MovieLister という名前のクラスを作成しました。また、その movieDirectedBy メソッドは、監督名に基づいて映画を検索する方法を提供します。実際にムービーの検索を担当するのは、MovieFinder インターフェイスを実装する MovieFinderImpl です。MovieLister クラスは、コンストラクターで MovieFinderImpl オブジェクトを作成します。
今のところ、すべて順調のようです。ただし、ファインダーを変更して、ファインダーを新しい実装に置き換える場合 (ムービー データがどのデータベースから来たのかを示すパラメーターを MovieFinder に追加するなど)、MovieFinderImpl クラスを変更するだけでなく、次のことも必要になります。 MovieLister コードで作成された MovieFinderImpl を変更します。
これは依存性注入が扱うカップリングです。 MovieLister で MovieFinderImpl を作成するこの方法では、MovieLister は MovieFinder インターフェイスに依存するだけでなく、MovieListImpl の実装にも依存します。ハードコーディングされた文字列やハードコーディングされた数値 (マジック ナンバー) のように、あるクラス内で別のクラスのオブジェクトを直接作成するこの種のコードは、カップリングにつながる悪臭です。 。同時に、ハードコーディングと同様に、新しいこと(オブジェクトの作成)には毒があることも覚えておく必要があります。
Hard Init によってもたらされる主な欠点は 2 つの側面です: 1) 前述のように実装を変更する場合、コードが作成された場所を変更する必要があります; 2) テストが容易ではなく、クラスこの方法で作成された (この記事の MovieLister 上) は単独でテストすることはできず、その動作は MovieFinderImpl と密接に結合されています。同時に、コードの可読性の問題も引き起こします (「コードの一部がテストしにくい場合」) 、それなら読みにくいはずです。」)。
2. 依存関係注入の実装方法
依存関係注入は実際には魔法ではありません。依存関係注入は日常のコードの多くで使用されていますが、私たちがそれに気づくことはめったにありません。また、切り離しのために依存関係注入を積極的に使用することはほとんどありません。ここでは注射に頼る3つの方法を簡単に紹介します。
2.1 コンストラクターインジェクション
個人的にはこれが最もシンプルな依存関係の注入方法です 上記コードの MovieList のコンストラクターを修正して、MovieFinderImpl の実装が MovieLister クラスの外部に作成されるようにしましょう。このように、MovieLister は、MovieFinder の実装ではなく、定義した MovieFinder インターフェイスのみに依存します。
public class MovieLister { private MovieFinder finder; public MovieLister(MovieFinder finder) { this.finder = finder; } ... }
2.2 セッター注入
同様に、作成された MovieFinder オブジェクトに渡すセッター関数を追加できます。これにより、MovieFinder でのこのオブジェクトのハード初期化も回避できます。
public class MovieLister { s... public void setFinder(MovieFinder finder) { this.finder = finder; } }
2.3 インターフェイス インジェクション
インターフェイス インジェクションはインターフェイスを使用して setter メソッドを提供し、その実装は次のとおりです。
まず、インジェクション用のインターフェースを作成します。
public interface InjectFinder { void injectFinder(MovieFinder finder); }
その後、MovieLister にこのインターフェイスを実装させます。
class MovieLister implements InjectFinder { ... public void injectFinder(MovieFinder finder) { this.finder = finder; } ... }
最後に、さまざまなフレームワークに従って依存する MovieFinder 実装を作成する必要があります。
3. 最後に
#依存関係の挿入により、依存関係と依存型の間の結合が軽減されます。依存型の実装を変更する場合、依存関係の実装を変更する必要はありません。同時に、依存型のテストでは、依存オブジェクトの独立した単体テストの目的を達成するために、モッキング オブジェクトを使用して元の依存型を置き換える方が便利です。
最後に、依存関係の注入は制御の反転を実装する 1 つの方法にすぎないことに注意してください。制御の反転のもう 1 つの一般的な実装は、依存関係のルックアップと呼ばれます。
以上がなぜphpは依存性注入を使用するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。