정적 유틸리티를 잘못 사용한 예
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 SpellChecker INSTANCE = new SpellChecker(...);
public boolean isValid(String word) { ... }
public List<String> ssuggestions(String typo) { ... }
}
⇒ 두 방식 모두 유연하지 않고, 테스트하기 어려움
사용하는 자원에 따라 동작이 달라지는 클래스에서는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않음
public class SpellChecker{
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary){
this.dictionary = Objects.requireNonNull(dictionary);
}
}
*팩터리 : 호출할 때마다 특정 타입의 인스턴스를 반복해서 만들어주는 객체
Mosaic create(Supplier<? extends Tile> tileFactory){...}
생성자에 자원 팩터리를 넘겨주는 방식
명시한 타입의 하위 타입이라면 무엇이든 생성할 수 있는 팩터리를 넘길 수 있음
class Tile {
// Tile 클래스의 구현
}
class Mosaic {
private List<Tile> tiles;
public Mosaic(Supplier<? extends Tile> tileFactory) {
this.tiles = new ArrayList<>();
// 기타 로직
}
}
→ Tile
의 서브클래스가 추가되더라도 Mosaic
의 코드 변경 없이 새로운 타일 타입을 추가할 수 있게됨