티스토리 뷰

반응형

클래스가 하나 이상의 자원에 의존할때

이런 클래스를 정적 유틸리티 클래스나 싱글턴 클래스로 만드는 경우

// 정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다
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 static final Lexicon dictionary = ...; // 사전에 의존
    private SpellChecker(...) {}
    public static SpellChecker INSTANCE = new SpellChecker(...);

    public static boolean isValid(String word){...}
    public static List<String> suggestions(String typo){...}

}

실전에서는 사전이 언어별로 따로 있기도 하고, 특수 어휘용 사전을 별도로 두기도 한다.

그렇기 때문에 위의 방법처럼 자원을 직접 명시하는 것은 이런 경우에 대응하기 어렵다.

여러 사전을 사용할 수 있도록 만들어보자.

final 한정자를 제거하고 다른 사전으로 교체할 수 있는 메서드를 추가할 수도 있지만,

이런 방법은 오류가 나기 쉽고 멀티스레드 환경에서 사용할 수 없다.

 

 

 

의존 객체 주입 방법

클라이언트가 원하는 자원을 사용하기 위해서 인스턴스를 생성할때 생성자에 필요한 자원을 넘겨주는 방식을 사용하자.

즉, 인스턴스 생성시에 의존 객체를 주입해준다.

// 의존 객체 주입 - 유연성과 테스트 용이성을 높여준다
public class SpellChecker{
    private final Lexicon dictionary;

    public SpellChecker(Lexicon dictionary){
        this.dictionay = Objects.requiredNonNull(dictionay);
    }

    public boolean isValid(String word){...}
    public List<String> suggestions(String typo){...}
}
  • Lexicon의 하위타입을 확장하여 여러 사전 사용 가능
  • 자원이 몇개든 의존관계가 어떻든 잘 작동
  • 자원의 불변을 보장
  • 생성자, 정적 팩터리, 빌더에도 응용 가능
  • 유연성과 테스트 용이성을 높여주지만, 의존성이 너무 많아지면 프로젝트의 코드가 어지러워진다. 이걸 해소하기 위해서 스프링과 같은 의존 객체 주입 프레임워크를 사용하면 프레임워크가 의존 객체 주입을 직접해준다.

 

 

 

팩터리 메서드 패턴 (Factory Method pattern)

의존 객체 주입을 응용하여 생성자에 자원 팩터리를 넘겨주는 방식을 사용할 수 있다.

팩터리 : 호출할 때마다 특정 타입의 인스턴스를 반복해서 만들어주는 객체 (Supplier)
//명시한 타입의 하위타입이라면 무엇이든 생성할 수 있는 팩터리를 넘길 수 있음
Mosaic create(Supplier<? extends Tile> tileFactory){..}

 

 

결론

클래스가 내부적으로 하나 이상의 자원에 의존하고 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.

이 자원을 클래스가 직접 명시하는 것도 좋지 않다.

→ 필요한 자원을 생성자에 넘겨 의존 객체 주입을 하도록 하자. 유연성, 재사용성, 테스트 용이성을 높여준다!

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday