-
이펙티브 자바 Item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라언어/Effective Java 2024. 5. 27. 15:54
사용하는 자원에 따라 동작이 달라지는 클래스는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.
1. 자원 직접 주입
대부분의 클래스는 여러 리소스에 의존한다. 책에서는 SpellChecker와 Dictionary를 예로 든다.
두 객체 사이에는 의존관계가 있다.
아래는 static 유틸리티를 잘못 사용한 예이다. - 이는 유연하지 않고 테스트가 어렵다.
public class SpellChecker { private static final Lexicon dictionary = ...; // 의존하는 리소스 (의존성) private SpellChecker() {} // 객체 생성 방지 public static boolean isValid(String word) { ... } public static List<String> suggestions(String typo) { ... } }
- 직접 자원을 명시하기 때문에, 테스트가 어렵다.
- 의존성을 바깥으로 분리하여 외부로부터 주입받도록 해야 한다. (의존 객체 주입 패턴)
2. 의존 객체 주입
의존 객체 주입은 유연성과 테스트 용이성을 높여준다.
public class SpellChecker { private final Lexicon dictionary; public SpellChecker(Lexicon dictionary) { this.dictionary = Objects.requireNonNull(dictionary); } public boolean isValid(String word) { return true; } public List<String> suggestions(String typo) { return null; } }
- 불변을 보장하여 변경될 일이 없다. 여러 클라이언트가 의존 객체를 안심하고 공유할 수 있다.
2. 팩토리 메서드 패턴
- 비슷한 변형으로 생성자에 자원 팩터리를 넘겨줄 수 있다.
- 자원 팩토리란 자원을 계속 찍어내는 객체를 말한다 (자바 8의 Supplier 인터페이스가 대표적이다)
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); // T 타입 객체를 찍어낸다 }
public class LottoTicketGenerator { private final NumberGenerator numberGenerator; public LottoTicketGenerator(Supplier<? extends NumberGenerator> numberGenerator) { this.numberGenerator = numberGenerator.get(); } }
결론적으로 클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원 클래스 동작에 영향을 주거나 받는다면 싱글톤이나 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.
또한 해당 자원을 클래스에 직접 때려박아도 안된다.
대신 필요한 자원을 생성자를 통해 (혹은 정적 팩토리, 빌더)에 넘겨주자
의존 객체 주입은 클래스의 유연성, 재사용성, 테스트 용이성을 개선해준다.
참고자료
https://javabom.tistory.com/73
'언어 > Effective Java' 카테고리의 다른 글
이펙티브 자바 Item7 - 다 쓴 객체의 참조를 해제하라 (0) 2024.05.28 이펙티브 자바 Item6 - 불필요한 객체 생성을 피하라 (0) 2024.05.27 이펙티브 자바 Item3 - private 생성자나 열거타입으로 싱글톤임을 보장하라 (0) 2024.05.27 이펙트브 자바 Item4 - 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) 2024.05.27 이펙티브 자바 Item2 - 생성자에 매개변수가 많다면 빌더를 고려하라 (0) 2024.05.27