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

rescogitans·2022년 4월 13일
0

이펙티브 자바

목록 보기
5/5

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

자원에 의존하는 클래스 구현: 사전에 의존하는 맞춤법 검사기 사례

부정적 예시

  1. 정적 유틸리티 클래스
public class SpellChecker {
    private final Lexicon dictionary =...;
    
    private SpellChecker() {} // 객체 생성 방지
    
    public static boolean isValid(String word) { ... }
    public static List<String> suggestions(String typo) { ... }
}
  1. 싱글톤
public class SpellChecker {
    private final Lexicon dictionary = ...;
    
    private Spellchecker(...) {}
    public static SpellChecker INSTANCE = new pellChecker(...);
    
    public boolean isValid(String word) { ... }
    public List<String> suggestions(String typo) { ... }
}
  • 1과 2는 모두 자원(사전)을 단 하나만 사용한다고 가정한다는 점이 단점이다.
    • 실제로는 다양한 자원을 사용할 수 있어야 한다.
    • 대안: dictionary 필드를 final하지 않게 만드는 방법
      • 오류를 내기 쉬우며 멀티스레드 환경에서 사용 불가
    • 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글톤 방식은 부적합하다.

대안: 의존 객체 주입 패턴

public class SpellChecker {
    private final Lexicon dictionary;
    
    public SpellChecker(Lexicon dictionary) {
    
}
  • 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식

  • 자원의 수나 의존관계와 무관하게 작동

  • 불변을 보장, 동일 자원 공유를 안전하게 할 수 있음

  • 생성자, 정적 팩터리, 빌더 모두에 적용 가능한 방법

  • 변형: 생성자에 자원 팩터리를 넘겨주는 방식

    • 한정적 와일드카드 타입(bounded wildcard type)을 이용해 팩터리 타입 매개변수를 제한해야
      • 예시
    Mosaic create(Supplier<? extends Tile> tileFactory) {...}
  • 단, 의존성이 많은 프로젝트에서는 코드를 어지럽힐 수 있다: 의존 객체 주입 프레임워크를 사용하여 해결하라

  • 의문사항: 왜 싱글톤을 사용해서 안 되나? 싱글톤에 DI 사용하면 되지 않나(스프링의 경우)?

0개의 댓글