📖본 포스팅은 'Effective java - 조슈아' 님의 책를 보고 작성되었습니다.
[하나 이상의 자원에 의존한 클래스 - 잘못된 예시들]
- 많은 클래스가 하나 이상의 자원에 의존한다.
- 아래는 자원에 의존한 클래스들의 잘못된 예시들이다.
[정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기가 어렵다.]
public class SpellChecker{
private static final Lexicon dictionary = ...;
//객체 생성 방지 -> 정적 유틸리티는 객체 생성을 원하지 않기에 이를 private 생성자로 방지해주어야 한다.
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) {...}
}
- 위의 두개의 코드 모두 하나의 사전만 사용한다고 가정했다는 점에서 그리 훌륭한 코드가 아니라고 보인다.
- 실전에서는 사전이 언어별로 있고 특수 어휘용 사전도 별도로 두기 때문에 사전 하나로 모든 쓰임에 대응할 수 없기에 매우 좋지 않은 코드라고 할 수 있다.
[의존 객체 주입 = 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방법]
public class SpellChecker{
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary){
this.dictionary = Objects.requireNonNull(dictionary);
}
public static boolean isValid(String word){ ... }
public static List<String> suggestions(String typo) {...}
}
- 사용하는 자원에 따라 동작이 달라지는 클래스는 정적 유틸리티 클래스나 싱글턴 방식은 적합하지 않다.
- 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식 = 의존 객체 주입
- 대신 클래스가 여러 자원 인스턴스를 지원해야 한다.
- 클라이언트가 원하는 자원(dictionary)을 사용해야 한다.
[의존 객체 주입의 장점]
- 불변을 보장한다.
- 같은 자원을 사용하려는 여러 클라이언트가 의존 객체를 안심하고 공유할 수 있다.
- 의존 객체의 주입은 생성자, 정적 팩터리, 빌더 모두에 똑같이 응용 가능하다.
- 의존 객체 주입은 유연성과 테스트 용이성을 개선해준다.
[의존 객체 주입의 단점]
- 코드가 수천 개나 되는 큰 프로젝트에서는 코드를 어지럽게 만든다.
- 그러나 이는 주스(Guice), 스프링(Spring) 같은 의존 객체 주입 프레임워크를 사용하면 해결할 수 있다.
[정리]
- 클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.
- 또한 클래스가 이 자원들을 직접 만들게 하는 것 역시 안 된다. 대신 필요한 자원을 (혹은 그 자원을 만들어주는 팩터리를 ) 생성자에 (혹은 정적 팩터리나 빌더) 넘겨주자
- 의존 객체 주입은 클래스의 유연성, 재사용성, 테스트 용이성을 개선해준다.
https://yeomylaoo.tistory.com/446
https://yeomylaoo.tistory.com/438?category=941231
Spring의 객체 주입에 대해서 정리한 포스팅 나중에 다시 기억이 안 날때 확인해서 볼 것
'Java > 이펙티브 자바(Effective Java)' 카테고리의 다른 글
[이펙티브 자바(Effective Java)][객체 생성과 파괴] - 7. 다 쓴 객체 참조를 해제하라 (0) | 2022.04.11 |
---|---|
[이펙티브 자바(Effective Java)][객체 생성과 파괴] - 6.불필요한 객체 생성을 피하라 (0) | 2022.04.08 |
[이펙티브 자바(Effective Java)][객체 생성과 파괴] - 4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2022.04.08 |
[이펙티브 자바(Effective Java)][객체 생성과 파괴] - 3. 생성자나 열거타입으로 싱글턴 임을 보증하라 (0) | 2022.04.08 |
[이펙티브 자바(Effective Java)][객체 생성과 파괴] - 2. 생성자에 매개변수가 많다면 빌더를 고려해라 (0) | 2022.04.05 |