Item 5、依存オブジェクト注入を使用


リソースを直接宣言するのではなく、依存オブジェクト注入を使用する


ほとんどのクラスは1つ以上のリソースに依存します.SpellCheckerが以下のように表現されることは珍しくない.
静的ユーティリティクラス(ツール4)
// 부적절한 static 유틸리티 사용 예 - 유연하지 않고 테스트 할 수 없다.
public class SpellChecker {

    private static final Lexicon dictionary = new KoreanDicationry();

    private SpellChecker() {
        // Noninstantiable
    }

    public static boolean isValid(String word) {
        throw new UnsupportedOperationException();
    }


    public static List<String> suggestions(String typo) {
        throw new UnsupportedOperationException();
    }
}

interface Lexicon {}
モノトーン実施(アイテム3)
// 부적절한 싱글톤 사용 예 - 유연하지 않고 테스트 할 수 없다.
public class SpellChecker {

    private final Lexicon dictionary = new KoreanDicationry();

    private SpellChecker() {
    }

    public static final SpellChecker INSTANCE = new SpellChecker() {
    };

    public boolean isValid(String word) {
        throw new UnsupportedOperationException();
    }


    public List<String> suggestions(String typo) {
        throw new UnsupportedOperationException();
    }

}
どちらも辞書を1冊しか使わないときによく見えます.実際には、各言語のスペルチェックで使用される辞書が異なり、テスト辞書も使用できます.
クラスによって使用されるリソースに応じて異なる動作を行う必要がある場合は、静的ユーティリティクラスとモノトーンを使用しないでください.
これらの要件を満たすことができるのは、インスタンスの作成時に作成者が必要とするリソースをインスタンスに渡す方法であり、これはオブジェクト注入に依存する形式である.
//의존 객체 주입은 유연성과 테스트 용이성을 높인다.
public class SpellChecker {

    private final Lexicon dictionary;

    public SpellChecker(Lexicon dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }

    public boolean isValid(String word) {
        throw new UnsupportedOperationException();
    }
    
    public List<String> suggestions(String typo) {
        throw new UnsupportedOperationException();
    }

}
依存オブジェクト注入は、ジェネレータ、静的ファクトリ、およびコンストラクタに適用できます.
1つの方法は、このモードの変形ジェネレータにリソースファクトリを渡すことです.この方法はjava 8によって紹介されたSupplier<T>インタフェースによって完全にこの工場として使用することができる.入力方法としては、通常、工場のタイプパラメータを制限するために、限定されたワイルドカードタイプを使用する必要がある.
Mosaic create(Supplier<? extends Tile> tileFactory) { ... }
依存オブジェクト注入は柔軟性とテストの使いやすさを向上させることができるが,依存性が数千個に達する大規模なプロジェクトでもコードの混乱をもたらす.この場合、大挙、スプリングなどの依存対象注入フレームを用いて除去することができる.

整理する


クラスが内部で1つ以上のリソースに依存し、これらのリソースがクラスの動作に影響を及ぼす場合は、単一のインスタンスと静的ユーティリティクラスは使用しないほうがいいです.