Book/Effective Java

[Book] ITEM 5) 리소스를 엮을 때는 의존성 주입을 선호하라

kkkkkkkkkkkk 2022. 3. 3. 11:43

Repository 로 예를 들어 보겠습니다.

InterfaceRepository 인터페이스가 save() 라는 기능을 가지고 있습니다.

public interface InterfaceRepository<T> {
    T save();
}

이를 구현한 MemoryBookRepository 클래스와 JdbcBookRepository 클래스를 생성합니다.

public class MemoryBookRepository implements InterfaceRepository<Book> {
    @Override
    public Book save() {
        return null;
    }
}
public class JdbcBookRepository implements InterfaceRepository<Book> {
    @Override
    public Book save() {
        return null;
    }
}

🥲  정적 유틸리티

BookService 라는 클래스를 생성합니다.

public class BookService {

    private static final InterfaceRepository<Book> repository = 
                                    new MemoryBookRepository();

    private BookService(){}

    public void create() {
        repository.save();
    }
}

BookService 클래스를 static utility 클래스 처럼 만들었고 MemoryBookRepository 의 정적 repository 라는 인스턴스를 가지고 있습니다.

우리가 데이터베이스랑 연결을 해서 테스트를 해보자고 할 때 클라이언트에서 인스턴스를 변경해야하는데 저 코드는 변경이 가능할까요??

이 Service 클래스를 유틸리티로 만든 것도 부적절합니다...ㅎㅎ

이렇듯 변경이 불가능하며 테스트 도 어려워지게 됩니다.

🥲  싱글톤

public class BookService {

    private static InterfaceRepository<Book> repository= new MemoryBookRepository();

    private BookService(){}

    private static final BookService SERVICE = new BookService();

    public void create() {
        repository.save();
    }
}

싱글톤으로도 구현해도 Repository 의 변경 에 유연하지 않고 테스트 도 어려워지게 됩니다.

이러한 문제점들을 우리는 의존성 주입으로 구현을 해봅시다.

😝  의존성 주입

public class BookService{

    private final InterfaceRepository<Book> repository;

    public BookService(InterfaceRepository<Book> repository) {
        this.repository = repository;
    }

    public void create() {
        repository.save();
    }
}

변경에 유연하며 테스트하기도 쉽습니다.