반응형
보통 클래스는 하나 이상의 자원에 의존한다.
예시가 생각나지 않아 책에 나온 예시를 참조 하였다.
맞춤법 검사기는 사전에 의존하게 되는데, 이런 클래스들을
유틸리티 클래스 또는 싱글턴으로 구현한 모습을 드물지않게 볼 수 있다.
// 정적 유틸리티
class SpellChecker {
private final Lexicon dictionary = new KoreanLexicon();
private SpellChecker() {}
public static boolean isValid(String word) {
//..
}
}
// 싱글턴
class SpellChecker {
private final Lexicon dictionary = new KoreanLexicon();
private SpellChecker() {}
public static SpellChecker INSTANCE = new SpellChecker();
public boolean isValid(String word) {
//..
}
}
두 케이스 모두 잘못사용한 예로 들 수 있다. -> 사전을 국어사전만 사용할 수 있음.
이때, 여러 사전을 사용할 수 있도록 사전을 교체하는 메서드(setter)를 추가하게 되면 오류를 유발할 수 있고,
멀티스레드 환경에서는 사용할 수 없다.(불변 보장X)
사용하는 자원에 따라 동작이 달라지는 클래스의 경우에는 정적 유틸리티 클래스, 싱글턴 클래스 방식이 적절하지않다.
대안으로 의존 객체 주입이 있다.
인스턴스를 생성할 때, 생성자에 필요한 자원을 넘겨주는 방식
// 의존성 주입
class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public static boolean isValid(String word) {
//..
}
}
자원이 몇개든 의존관계가 어떻든 상관없이 잘 작동하고
불변을 보장하여 여러 클라이언트가 안심하고 사용 가능하다.
생성자, 정적 팩터리, 빌더 모두 적용가능.
생성자에 자원 팩터리를 넘겨주는 방식도 가능
class Mosaic {
public static Mosaic create(Supplier<? extends Tile> tileFactory) {
Tile tile = tileFactory.get();
// ..
}
}
// 상위 타입
interface Tile {
void setColor(String color);
}
// 하위 타입
class CheckTile implements Tile {
public void setColor(String color) {}
}
// 검은색 컬러 속성을 가지게 하는 객체 자원 팩터리를 넘겨준다.
Mosaic m = Mosaic.create(() -> {
CheckTile checkTile = new CheckTile();
checkTile.setColor("black");
return checkTile;
});
명시된 타입의 하위 타입이라면 무엇이든 생성할 수 있는 팩터리를 넘길 수 있다.
의존성이 많아지면 코드를 어지럽게 만들기도 한다.
스프링같은 프레임워크를 사용하면 간단하게 해소할 수 있다.
반응형
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA] Effective Java - 7. 다 쓴 객체 참조를 해제하라 (0) | 2022.11.22 |
---|---|
[JAVA] Effective Java - 6. 불필요한 객체 생성을 피하라. (1) | 2022.09.22 |
[JAVA] Effective Java - 4. 인스턴스화를 막으려면 private 생성자를 사용 (0) | 2022.09.06 |
[JAVA] Effective Java - 3. private 생성자나 열거 타입으로 싱글턴 보증 (0) | 2022.08.31 |
[JAVA] Effective Java - 2. 점층적 생성자, 자바 빈즈, 빌더 패턴 (0) | 2022.08.17 |