Gidhub BE Developer

[Effective Java] 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

2020-06-26
goodGid

기존 책 내용을 필자가 생각하기에 이해하기 쉽게 조금 변형하였습니다.

의존 객체 주입

  • 사용하는 자원에 따라

    동작이 달라지는 클래스에는

    정적 유틸리티 클래스싱글턴 방식이 적합하지 않다.

  • 오히려 의존 객체 주입 패턴을 사용하는게 훨씬 좋다.

    즉 인스턴스 생성 시 생성자에 필요한 자원을 넘겨준다.

  • 잘 이해가 되지 않을테니 Example을 통해 이해해보자.


Example

  • 맞춤법 검사를 하고 싶다는 요구 사항이 있고

    요구 사항을 충족시키기 위해

    맞춤법 검사를 하는 클래스를 구현해보자.

  • 위 요구 사항을 충족시키는 클래스를 만들어야 한다면

    필자라면 다음과 같이 2가지 방법을 생각했을 것이다.


1 정적 유틸리티 클래스

public class SpellChecker {
    
    private static final Dictionary dic = ...;
    
    private SpellChecker() {} // 객체 생성 방지
    
    public static boolean isVaild(String word) { 
        return true || false;
    }
}

// 사용법 : SpellChecker.isVaild("goodGid")

2. 인스턴스를 중복으로 생성할 필요가 없으므로 싱글턴 클래스 생성

public class SpellChecker {
    
    private final Dictionary dic = ...;
    
    private SpellChecker() {} // 객체 생성 방지

    public static SpellChecker INSTANCE = new SpellChecker(...);
    
    public static boolean isVaild(String word) {
        return true || false;
    }
}

// 사용법 : SpellChecker.INSTANCE.isVaild("goodGid")

Problem

  • 기능상 문제는 없다.

    하지만 요구 사항이 변경되면 문제가 발생한다.

  • 만약 요구 사항이 1개의 Dictionary를 사용하는 게 아니라

    유저마다 사용하고자 하는 Dictionary를 사용하도록 변경해야 한다면

    현재는 하드 코딩으로 Dictionary를 선언하였기 때문에

    사용자가 원하는 Dictionary로 변경할 수 없다.


Solution

public class SpellChecker {

    private final Dictionary dic;
    
    // 의존성 주입
    public SpellChecker(Dictionary dictionary){
    	this.dic = dictionary
    }
    
    public static boolean isVaild(String word) {
        return true || false;
    }
}
  • 의존 객체 주입하는 방식으로

    클래스를 수정하였기 때문에

    Dictionary가 몇 개든 요구 사항을 충족시킬 수 있게 된다.


Summary

  • 가장 처음에 언급했던 문장을 다시 보면 다음처럼 해석할 수 있다.

    사용하는 자원에 따라 = 사용자가 원하는 Dictionary

    동작이 달라지는 클래스에는 = 사용자가 원하는 Dictionary로 맞춤법을 검사한다.

    정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. = 정적 클래스 혹은 싱글턴은 변경할 수 없다.

  • 즉 클래스가 내부적으로 하나 이상의 자원에 의존하고

    그 자원이 클래스 동작에 영향을 준다면

    싱글턴정적 유틸리티 클래스는 사용하지 않는 것이 좋다.

  • 이 자원들을 클래스가 직접 만들게 해서도 안 된다.

    대신 필요한 자원을 생성자를 통해 넘겨주자.

  • 의존 객체 주입이라 하는 이 기법은

    클래스의 유연성, 재사용성, 테스트 용이성을 개선해준다.


Reference


Comments

Index