땀두 블로그

[도서] Effective Java - Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라. 본문

도서

[도서] Effective Java - Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라.

땀두 2022. 4. 15. 22:11

이펙티브 자바 3판을 읽으면서 내용을 정리하는 포스트입니다. 혹시 틀린 부분이나 잘 못 설명한 부분이 있으면 댓글로 남겨주시면 수정하도록 하겠습니다.

Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라.

정적 유틸리티와 싱글톤을 잘못 사용한 예시이다.

//정적 유틸리티
public class SpellChecker{
    private static final Lexicon dictionary;
    private SpellChecker() {}

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

//싱글톤
public class SpellChecker{
    private static final Lexicon dictionary;
    private SpellChecker() {} 
    public static SpellChecker INSTANCE = new SpellChecker();

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

이 두 코드는 유연하지 않고, 테스트가 어렵다. 그 이유는 아래와 같다.

  • 사용할 사전이 단 한 가지라고 생각하고 있다.
  • 의존하는 객체를 직접 생성하고 있다.

여기서 dictionary 필드에서 final 한정자를 제거하고 다른 사전으로 교체하는 메서드를 추가하면 여러 사전을 사용할 수 있지만, 오류를 내기 쉽고, 멀티스레드 환경에서는 사용이 불가능하다.

사용하는 자원에 따라 동작이 달라지는 클래스는 정적 유틸리티 클래스나 싱글톤 방식이 적합하지 않다. 이러한 경우에는 클래스가 여러 자원 인스턴스를 지원하고, 클라이언트가 원하는 자원을 사용하도록 해야 한다.

public class SpellChecker{
    private final Lexicon dictionary;

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

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

의존성 객체 주입(dependency injection)

  • 필요한 객체를 직접 생성하는 것이 아닌 외부로부터 필요한 객체를 받아서 사용하는 것
의존 객체 주입 패턴의 장점
  • 유연하고 테스트가 쉽다.
  • 자원의 개수나 의존관계에 상관없이 잘 동작한다.
  • 여러 클라이언트가 의존 객체들을 공유 가능하다.

의존 객체 주입은 유연성과 테스트 용이성을 개선해주지만, 의존성이 많은 경우 코드를 어지럽게 할 수 있지만 의존 객체 주입 프레임워크인 대거, 주스, 스프링 등을 사용하면 해소 가능하다.

​ ex) 스프링 의존성 주입

  • 외부에서 객체를 생성한 후 의존성을 주입시키는 방식으로, 생성자 이용방식, Field 변수 이용방식, setter 이용방식이 있다.
Comments