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

일고잉·2021년 7월 29일
0

클래스, 자원 의존

많은 클래스는 하나 이상의 자원에 의존한다
예) 사전에 의존하는 맞춤법 검사기 클래스

정적 유틸리티 클래스로 구현

정적 유틸리티를 잘못 사용한 예
유연하지 않고 테스트하기 어렵다

public class SpellChecker{
    private static final Lexicon dictionary = ...;
    
    private SpellChecker(){} // 인스턴스 생성 방지
    
    public static boolean isValid(String word){ ... }
    ...
}

싱글턴도 가능

싱글턴을 잘못 사용한 예
유연하지 않고 테스트하기 어렵다

public class SpellChecker{
    private static final Lexicon dictionary = ...;
    
    private SpellChecker(...){}
    public static SpellChecker INSTANCE = new SpellChecker(...);
    
    public static boolean isValid(String word){ ... }
    ...
}

둘 다 사전을 하나만 사용함 -> 확장할 수 없다
자원에 따라 동작이 달라지는 클래스는 정적 유틸리티 클래스나 싱글턴이 적합하지 않다
사용자가 원하는 자원을 사용할 수 있게 해야하는데..

인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주면 된다!

의존 객체 주입 패턴

public class SpellChecker{
    private static final Lexicon dictionary;
    
    public SpellChecker(Lexicon dictionary){
    	this.dictionary = Objects.requireNonNull(dictionary);
    }
    
    public static boolean isValid(String word){ ... }
    ...
}

자원이 몇 개든 의존 관계가 어떻든 상관없다
객체가 불변임을 보장하여 여러 클라이언트가 의존 객체들을 안심하고 공유할 수 있다
생성자, 정적 팩토리, 빌더에 똑같이 적용 가능

의존 객체 주입 프레임워크 Dagger, Guice, Spring

정리

클래스가 내부적으로 하나 이상의 자원에 의존하고,
그 자원이 클래스 동작에 영향을 준다면 싱글턴정적 유틸리티 클래스는 사용하지 않는 것이 좋다.
자원들을 클래스가 직접 만들게 해서도 안된다.
대신, 필요한 자원 또는 자원을 만들어주는 팩토리를 생성자, 정적 팩토리, 빌더에 넘겨주자. 의존 객체 주입이라 하는 이 기법은 클래스의 유연성, 재사용성, 테스트 용이성을 크게 개선해준다.

0개의 댓글