본문은 Effective Java를 읽고 간단하게 정리한 글입니다. 필요에 따라 생략/수정된 부분이 있을 수 있으며, 내용이 추후 변경될 수 있습니다.
사용하는 자원에 따라 동작이 달라지는 클래스에는 static 유틸리티 클래스나 싱글턴 방식을 사용하지마라
static 유틸리티 클래스(아이템4) 방식
public class SpellChecker {
private static final Lexicon dictionary = ...;
private SpellChecker() {} // 객체 생성 방지
public static boolean isValid(String word) { ... }
public static List<String> suggestions(String typo) { ... }
}
싱글턴(아이템3) 방식
public class SpellChecker {
private final Lexicon dictionary = ...;
private SpellChecker(...) {}
public static final SpellChecker INSTANCE = new SpellChecker(...);
public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}
위 두 방식은 유연하지 않고 테스트하기 어렵다
즉, 의존하는 객체를 바꾸기 어렵다 -> 테스트 시 mock객체를 주입하기 어렵다
의존 객체 주입(의존성 주입)
의존 객체 주입 방식
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}
class Lexicon {}
- 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨준다
- 좀 더 유연하게 의존하는 객체를 바꿀 수 있다
의존 객체 주입 장단점
장점
- 자원의 개수나 의존 관계가 어떻든 상관없이 잘 작동한다
- 해당 객체를 사용하는 클라이언트는 내부를 모르고 사용할 수 있다
- 불변을 보장하여 여러 클라이언트가 의존 객체들을 안심하고 공유할 수 있다
- 객체 생성시에 의존성이 주입되므로(final)
- 생성자, 정적 팩터리, 빌더 모두에 똑같이 응용 가능
- 생성자에 자원 팩터리를 넘겨주는 방식으로 사용 가능
- Tile을 만들 수 있는 tileFactory를 매개변수로 넘긴다
- create를 통해 Tile로 구성된 Mosaic타입의 객체가 반환된다
- 쉽게 말해 의존하는 자원을 만들어주는 팩터리를 넘김으로써 의존성 주입을 할 수 있다는 말이다
- 팩터리란 호출할 때마다 특정 타입의 인스턴스를 반복해서 만들어주는 객체를 의미한다
Mosaic create(Supplier<? extends Tile> tileFactory) { ... }
단점
- 의존성이 수천 개나 되는 큰 프로젝트에선 코드의 가독성을 떨어트릴 수 있다
- 우리가 주로 사용하는 Spring이나 Dagger, Guice와 같은 의존 객체 주입 프레임워크를 사용하여 이를 해결할 수 있다
정리
- 클래스가 내부적으로 하나 이상의 자원에 의존하고 그 자원이 클래스 동작에 영향을 준다면 의존성 주입 방식을 사용하라
- 클래스가 필요로 하는 자원을 직접 만들게 하지마라
- 유연성이 떨어진다
- 대신 필요한 자원(또는 그 자원을 만들어주는 팩터리를) 생성자에 (혹은 정적 팩터리나 빌더)에 넘겨준다
'책 > Effective Java' 카테고리의 다른 글
[이펙티브 자바] 아이템7: 다 쓴 객체 참조를 해제하라 (0) | 2022.04.19 |
---|---|
[이펙티브 자바] 아이템6: 불필요한 객체 생성을 피하라 (0) | 2022.04.18 |
[이펙티브 자바] 아이템4: 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2022.04.18 |
[이펙티브 자바] 아이템3: private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2022.04.18 |
[이펙티브 자바] 아이템2: 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.04.18 |