Book Review/effective-java

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

jay Joon 2021. 1. 30. 01:03

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

 

KJJ924/effective-java

:pencil2: 이펙티브 자바 3판 정리. Contribute to KJJ924/effective-java development by creating an account on GitHub.

github.com