ITEM 5
자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
클래스 내부에 하나 이상의 자원에 의존하고 해당 자원이 클래스 동작에 영향을 준다면 생성자를 통해 의존 자원을 주입받자는 의미이다.
해당 기법은 클래스의 유연성 , 재사용성,테스트 용이성을 개선해준다.
위 구절이 해당 아이템이 말하고자하는 핵심이다.
이제 코드를 보며 이해를해보자.
무기 인터페이스
public interface Weapon {
//공격을 합니다.
void attack();
}
정적 유틸리티 방식
public class Warrior {
private final Weapon weapon = new Sword(); // 전사는 weapon 이라는 자원을 직접 생성하여 의존하고있다.
private Warrior(Weapon weapon) {} //객체 생성금지
public static void attack(){
weapon.attack(); // 무기 자원이 해당 전사 클래스의 동작에 영향을 준다.
}
}
여기 전사(Warrior)라는 클래스가 있다.
전사라는 클래스는 무기(Weapon)이라는 자원을 의존하고 있다.
자 해당 방식(정적 유틸리티 방식)으로 코드를 생성할 때 이 전사라는 객체는 오로지 Sword 만 사용할 수 있다.
만약 더 좋은 무기를 가지고 있어도 이 전사는 무기를 변경할 수 없다.
해당 방식을 이러한 경우에서 사용하는 건 바람직하지 않는 거 같다.
여기서 이러한 경우란?
사용하는 자원에 따라 동작이 달라지는 클래스를 의미한다.
자 이제 자원에 대한 주입은 클라이언트에게 책임을 넘겨서
전사라는 인스턴스를 생성할 때 생성자를 통해 필요한 자원(무기)을 넘겨주는 방식을 사용해보자.
의존 객체 주입 방식
public class Warrior {
private final Weapon weapon; // 무기라는 자원을 의존하고있지만 직접 생성하지않고 있다.
public Warrior(Weapon weapon) {
this.weapon = Objects.requireNonNull(weapon); //해당 인스턴스가 만들어 질때 무기라는 의존성을 주입 받기를 원한다.
}
public void attack(){
weapon.attack(); // 주입받은 무기를 이용하여 공격을 진행한다.
}
}
자 여기서 핵심은 전사라는 클래스는 Weapon이라는 자원을 구체적으로 알고 있지 않다.
클라이언트가 어떤 무기를 넘겨주냐에 따라 전사 클래스는 해당 무기에 맞는 공격을 진행할 수 있다.
즉 전사가 무기를 변경할 때마다 전사 클래스의 코드 변경은 일어나지 않는다는 뜻이다.
해당 전사 클래스를 인스턴스를 만들 때 클라이언트가 어떤 무기를 주입하냐 에 따라 전사의 행동은 결정된다.
클라이언트 코드.
public static void main(String[] args) {
Weapon dagger = new Dagger();
Weapon sword = new Sword();
Warrior warrior = new Warrior(dagger); //여기서 단검을 주입하거나 ,검을 주입하나에 따라 전사의 공격행동은 변경된다.
}
이렇게 의존 객체를 주입하여 사용하면 엄청난 유연성과 테스트를 작성할 때 매우 편하다.
하지만 이러한 방식은 의존성이 수천 개 이상 넘는 프로젝트에서 직접 관리하려고 하면 코드가 복잡해질 수 있다.
그러나
그러한 문제점은 스프링 , 주스 , 대거 같은 프레임워크를 활용한다면 해소를 할 수 있다.
해당 예제 코드는 저의 깃헙에서 찾아보실수 있습니다.
github.com/KJJ924/effective-java/tree/master/src/main/java/com/jaejoon/demo/item5
'Book Review > effective-java' 카테고리의 다른 글
[ITEM7] 다 쓴 객체 참조를 해제하라 (0) | 2021.02.02 |
---|---|
[ITEM6] 불필요한 객체 생성을 피하라 (0) | 2021.01.31 |
[ITEM 4] 인스턴스화를 막으려거든 private 생성자를 사용하라 (1) | 2021.01.29 |
[ITEM3] private 생성자나 열거타입으로 싱글턴임을 보증하라 (0) | 2021.01.27 |
[ITEM 2] 생성자에 매개변수가 많다면 빌더를 고려하라 (1) | 2021.01.26 |