티스토리 뷰
매우 쉬운 내용이다.
코드 안에 어떤 객체를 박아두고 쓰지 말자는 이야기이다.
// 부적절한 static 유틸리티 사용 예 - 유연하지 않고 테스트 할 수 없다.
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 final Lexicon dictionary = ...;
private SpellChecker() {}
public static final SpellChecker INSTANCE = new SpellChecker();
public boolean isValid(String word) {...}
public List<String> suggestions(String typo) {...}
}
사전이라는 것은 언어마다 다양하게 존재할 수 있고 쓰임새에 따라 다른 여러 사전이 존재할 수 있다.
dictionary라는 객체를 SpellChecker 객체의 내부에서 미리 선언하면 다양한 사전에 대한 대응을 하기 쉽지 않다.
아이템 3에서 싱글톤으로 클래스를 구성하면 테스트가 어렵다는 내용이 이해가 간다.
이렇게 제공되는 자원에 따라 다른 동작을 하게 클래스를 구성하고 싶으면 static 팩토리 메소드와 싱글톤으로 클래스를 구성하는 것은 적절하지 않다.
이를 해결하기 위한 손쉬운 방법은 클래스가 생성될 때 자원을 넘겨주는 방식이다.
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) {...}
}
의존 객체 주입 방식은 생성자, static 팩토리 메소드, 빌더 패턴에 모두 적용될 수 있다.
이 패턴을 변형한 방식이 생성자에 자원 팩토리를 넘겨주는 방식이 있다.
바로 앞에서 계속 나왔던 functional Interface인 Serpplier<T>가 있다.
요 친구는 자바가 지원해주는 파라미터를 받지 않고 어떤 인스턴스를 반환하도록 구현하거라~라는 인터페이스이다.
Mosaic create(Supplier<? extends Tile> tileFactory) { ... }
이 인터페이스를 매개변수로 받기 위해서는 와일드카드 패턴을 사용해야 한다.
아이템 31에 해당 내용이 등장하는데, 요약하면 Supplier<T extends Tile>과 같이 구현하면
Supplier<Tile> 과 Supplier<Tile의 하위 타입>을 받고 싶다는 의미로 사용하지만
Tile과 Tile의 하위 타입은 상속관계가 성립하지만 이 둘을 감싸고 있는 Supplier는 상속관계가 성립하지 않는다.
이때 와일드카드 패턴을 사용하여 Supplier 내부 친구가 Tile의 하위타입이다라고 명시할 수 있다.
의존 객체 주입이 유연성과 테스트를 용이하게 해 주지만 로직이 커지면 수천 개의 의존성 객체들은 코드들을 어지럽게 만든다.
이때 Dagger, Juice, Spring과 같은 프레임워크들이 이를 해결해 준다. DI 얘기인 듯하다 ㅎㅎ
'Book > Effective Java' 카테고리의 다른 글
Effective Java - Item 7. 다 쓴 객체 참조를 해제하라 (0) | 2023.01.07 |
---|---|
Effective Java - Item 6. 불필요한 객체 생성을 피하라 (0) | 2023.01.05 |
Effective Java - Item 4. 인스턴스화를 막으려거든 private 생성자를 사용하라. (0) | 2023.01.02 |
Effective Java - Item 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2023.01.02 |
Effective Java - Item 2. 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2023.01.02 |