これは、 初心者のAndroid開発者向けのDagger 2シリーズの2番目の記事です。 最初の記事を読んでいない場合は、 ここにいます 。
一連の記事
- 初心者のAndroid開発者向けの短剣2。 はじめに
- 初心者のAndroid開発者向けの短剣2。 依存性注入 パート1(ここにいます) 。
- 初心者のAndroid開発者向けの短剣2。 依存性注入 パート2
- 初心者のAndroid開発者向けの短剣2。 ダガー2。パート1 。
- 初心者のAndroid開発者向けの短剣2。 ダガー2。パート2 。
- 初心者のAndroid開発者向けの短剣2。 ダガー2.アドバンス。
パート1 - 初心者のAndroid開発者向けの短剣2。 ダガー2.アドバンス。
パート2
一連の記事の前半
前回の記事では、依存関係について説明しました。 依存関係とは何か、そのタイプ、開発プロセスへの影響、プロジェクトの持続可能性について説明しました。
依存性注入(DI)とは何ですか?
先に、依存関係とは何か、そしてそれがプロジェクトにどのように影響するかを理解しました。 次に、依存性注入とは何かを見てみましょう。
依存関係の注入を逆アセンブルする前に、依存関係に囲まれるトラップを回避する方法を理解する必要があります。 White Walkers (White Walkers)としての難しい関係(難しい依存関係)の問題。 私たちは彼らの軍隊に加わるべきではありません。逆に、彼らを打ち負かす方法を見つける必要があります。
メディア
ハード接続の問題またはホワイトウォーカーズの問題を解決するための戦略
強い絆の問題を解決または防止するための明確な計画が必要です。 この戦略または計画は、 依存性注入(DI)と呼ばれます。 つまり、ホワイトウォーカーを殺すには、燃やすかドラゴンガラスの武器を使用する必要があります。 同様に、強い関係を回避するには、依存性注入を使用する必要があります。
依存関係の注入は、強い関係を防ぐための1つの方法にすぎません。 他の多くの方法があります。 Android開発の場合、この方法は最も単純であると考えられており、多くの大規模プロジェクトでは依存性注入戦略を使用しています。
依存性注入方法
依存性注入は、あるオブジェクトが別のオブジェクトの依存性を提供する方法です。 依存関係は、使用できるオブジェクトです( service )。 インジェクション(インジェクション)は、この依存関係を使用する依存オブジェクト( client )への依存関係の転送です。 サービスはクライアントの状態の一部です 。 クライアントがサービスを作成または検索できるようにする代わりに、サービスをクライアントに転送することは、 Dependency Injection(DI)設計パターンの基本的な要件です。
これをGame of Thronesと比較してください。 Cerseiは大戦の準備をしています。 彼女の王国のすべてのお金を燃やすのではなく、彼女はブラボース鉄銀行からローンを取得しようとしています。 この状況では、お金は中毒です。 すべての家は戦争をするのにお金が必要です。 したがって、外部オブジェクト(鉄の銀行)は、依存オブジェクト(家)に依存関係(お金)を導入します。
言い換えると、依存関係の実装は制御反転の概念に基づいており、これはクラスが外部から依存関係を受け取ることを示唆しています。 簡単に言えば、どのクラスも別のクラスをインスタンス化するべきではありませんが、構成クラスからすべてのインスタンスを受け取るべきです。
例1
話をやめる。 コードを解析しましょう。 2つのシナリオがある小さな例を考えてみましょう。 最初のシナリオでは、強い依存関係を持つ複数のクラスを作成します。つまり、依存関係の注入を使用しません。 次に、「依存性注入」パターンに従って、強い結合を取り除きます。
シナリオ1.依存性注入を使用しない
問題:ろくでなしの戦い- スタークとボルトンは、北を占領する戦争の準備をしている。 彼らを準備し、戦争に持ち込む必要があります。
メディア
この例には多くの家を含めることができるため、共通の
House
インターフェースを作成し、その中に
prepareForWar()
および
reportForWar()
メソッドを
reportForWar()
ます。
public interface House { void prepareForWar(); void reportForWar(); }
次に、
Starks
Boltons
と
Boltons
クラスを作成します。 クラスは
House
インターフェースを実装します。
public class Starks implements House { @Override public void prepareForWar() { //- System.out.println(this.getClass().getSimpleName()+" prepared for war"); } @Override public void reportForWar() { //- System.out.println(this.getClass().getSimpleName()+" reporting.."); } }
public class Boltons implements House { @Override public void prepareForWar() { //- System.out.println(this.getClass().getSimpleName()+" prepared for war"); } @Override public void reportForWar() { //- System.out.println(this.getClass().getSimpleName()+" reporting.."); } }
注:
this.getClass().getSimpleName()
はクラス名を返すだけです
次に、両方の家を戦争に持ち込む必要があります。
War
クラスを作成して、両方の家に戦争の準備と報告を依頼しましょう。
public class War { private Starks starks; private Boltons boltons; public War(){ starks = new Starks(); boltons = new Boltons(); starks.prepareForWar(); starks.reportForWar(); boltons.prepareForWar(); boltons.reportForWar(); } }
戦争の分析
War
クラスのコンストラクターを検討してください。 仕事をするためには、
Starks
と
Boltons
2つのクラスが必要です。 これらのクラスはコンストラクター内で作成され、戦争の準備と報告を行います。
適切に設計されたオブジェクト指向アプリケーションでは、各オブジェクトに最小限の責任があり、オブジェクトはほとんどの作業を他の人に依存しています。 この例では、
War
クラスは
Starks
と
Boltons
依存しています。 これらは
War
クラスの依存関係です。 彼らなしでは
War
は機能しません。 クラスが実際の機能を実行する前に、すべての依存関係が何らかの方法で満たされる必要があります。 この例のwarクラスの依存関係は、コンストラクターでクラスをインスタンス化することで満たされます。
クラスコンストラクター内で依存関係を作成するオプションは、小さなアプリケーションでは非常にうまく機能しますが、プロジェクトの成長に伴い不利な点が生じます。
まず、クラスは非常に柔軟性に欠けます。 たとえば、アプリケーションを複数のプラットフォームまたは複数のモードで実行する必要がある場合、
Boltons
クラスを別のクラスに置き換えるか、複数のオブジェクトに分割する必要があります。 これは簡単ではありません。
第二に、これらのクラスを単独でテストすることはできません。
War
インスタンスを作成すると、最終的に
War
クラスでテストされる2つの他のオブジェクトが自動的に作成されます。 これは、オブジェクトの1つが高価な外部リソースに依存している場合(たとえば、
Allies
(allies)またはオブジェクト自体の1つが他の多くに依存している場合)に問題になる可能性があります。
前述のように、 強い依存関係と戦うことは、適切な武器なしでホワイトウォーカーと戦うようなものです。
まとめ
この記事では、依存関係と依存関係の注入について詳しく説明しました。 他のクラスのインスタンスを作成するクラスはありませんが、構成クラスからすべてのインスタンスを受け取る必要があります。
依存性注入は、強い結び付きの問題を解決または防止する方法です。 外部から依存関係を提供することにより、このメソッドはクラスを独立、テスト可能、保守可能にします。
また、 ハード依存関係の例を見て、ろくでなしの戦いのシナリオを作成しました。
次は?
次回の記事では、従来のアプローチで依存性注入テンプレートを使用して
War
クラスを実装します。