[Effectiva-Java] Item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

imcool2551·2022년 2월 7일
0

Effective-Java

목록 보기
5/8
post-thumbnail

1. 자원을 직접 명시하는 방식의 문제점


많은 클래스가 하나 이상의 자원에 의존한다. 사전 클래스에 의존하는 맞춤법 검사기 클래스를 살펴보자.

public class SpellChecker {
    private static final Lexicon dictionary = new EnglishDictionary();

    private SpellChecker() {} // 객체 생성 방지

    public static boolean isValid(String word) {...}
    public static List<String> suggestions(String typo) {...}
}
public class SpellChecker {
    private final LexiconDictionary dictionary = new EnglishDictionary();

    private SpellChecker(...) {}
    public static SpellChecker INSTANCE = new SpellChecker(...);

    public boolean isValid(String word) {...}
    public List<String> suggestions(String typo) {...}
}

첫 번째 클래스는 정적 유틸리티 클래스다. 두 번재는 싱글턴 클래스다.

두 방식 모두 검사기 클래스가 필요한 자원인 사전을 직접 명시하고 있다. 즉, 단 하나의 사전만을 사용한다고 가정한 것이다. 그러나, 실제론 맞춤법 검사기는 언어별로 사전이 따로 있고 테스트를 위한 사전도 필요하게 될 수 있다.

사전의 final 키워드를 빼고 세터 메서드를 통해 사전을 교체하는 방법이 있긴하다. 그러나 이 방법은 어색하고 오류가 나기 쉽다. 무엇보다 멀티스레드 환경에서는 사용할 수 없다. 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.

2. 의존 객체 주입


자원을 직접 명시하는 방법보다 더 좋은 방법이 있다. 인스턴스를 생성할 때 필요한 자원을 넘겨주는 의존 객체 주입 방식이다.

public class SpellChecker {
    private final Lexicon dictionary;

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

    public boolean isValid(String word) {...}
    public List<String> suggestions(String typo) {...}
}

의존 객체 주입을 사용하면 자원을 명시하는 책임이 클래스 내부에서 외부로 바뀐다. 즉, 사용자가 원하는 사전을 사용하는 맞춤법 검사기를 얼마든지 만들 수 있게 된다. 또한 불변성(아이템 17)이 보장된다. 의존 객체 주입 방식은 정적 팩터리, 빌더에도 똑같이 응용할 수 있다.

3. 자원 팩터리를 주입하는 방식


의존객체 주입을 자원 팩터리를 넘겨줄 수도 있다. 팩터리란 호출할 때마다 특정 타입의 인스턴스를 반복해서 만들어주는 객체를 말한다. 자바8의 Supplier<T> 인터페이스가 팩터리의 예다. Supplier<T>를 매개변수로 받는 메서드는 한정적 와일드 카드(아이템 31)를 통해 타입 매개변수를 제한해야 한다. 예를 살펴보자.

Mosaic create(Supplier<? extends Tile> tileFactory) { ... }

create 메서드는 Tile 타입을 제공하는 팩터리 객체를 주입 받아서 모자이크 객체를 만든다.

4. 결론


의존 객체 주입을 사용하면 유연성, 재사용성, 테스트 용이성을 개선해준다. 그러나 의존성이 많아질 수록 코드를 어지럽게 만들 수 있다. 스프링 같은 의존 객체 주입 프레임워크는 의존성 주입을 적극 활용하면서도 코드를 어지럽게 만들지 않을 수 있도록 도와준다.

profile
아임쿨

0개의 댓글