<React.js, 스프링 부트, AWS로 배우는 웹 개발 101>(김다정 지음)을 따라 TO-DO 앱을 하나 만들 예정이다.
앞으로 쓸 대부분의 포스팅(이미지/글)은 위의 서적을 참고/출처로 작성되었음을 미리 밝힌다.
→ 생성자 내부에서 오브젝트 초기화
public class TodoService {
private final FileTodoPersistence persistence;
public TodoService() {
this.persistence = new FileTodoPersistence;
}
public void create(...) {
...
persistence.create(...);
}
}
Todo 애플리케이션에는 TodoService 클래스가 있고 이 클래스가 Todo 목록을 관리하는 기능을 제공한다고 가정하자.
TodoService는 FileTodoPersistence를 사용한다.
FileTodoPersistence가 파일에 Todo 목록을 저장할 수 있도록 도와주는 클래스일 경우 TodoService는 FileTodoPersistence 없이는 제 기능을 하지 못한다.
따라서 TodoService는 FileTodoPersistence에 의존(dependant)한다.
여기서는 FileTodoPersistence에 의존하는 TodoService가 RileTodoPersistence 오브젝트를 생성하고 관리한다.
그런데 만약에 어떤 상사가.. Todo 목록을 파일 말고 Database에 저장하자고 한다면? → FileTodoPersistence를 DatabaseTodoPersistence 자료형으로 모두 바꾸고 생성자에서 DatabaseTodoPersistence를 구현해야 한다.
그런데 만약에 또 상사가.. Database 말고 AWS S3를 쓰자고 한다면..? 그 회사를 나와야한다. 아니지.. DatabaseTodoPersistence 대신 S3TodoPersistence를 생성하도록, DatabaseTodoPersistence를 구현한 모든 코드들을 전부 수정해야한다.
--> 이것 말고도 유닛 테스트 작성이 어렵다는 문제가 있는데, 이 부분은 설명이 짧고 내 이해도 어려워서 일단 넘어간다.
이런 문제를 해결하는 것이 의존성 주입이다.
1) 생성자를 이용한 의존성 주입, 서비스 코드
public class TodoService {
private fical ITodoPersistence persistence; // 인터페이스
public TodoService(ITodoPersistence persistence) {
this.persistence = persistence;
}
public void create(...) {
...
persistence.create(...);
}
public static void main(String[] args) {
ItodoPersistence persistence = new FileTodoPersistence();
TodoService service = new TodoService(persistence);
}
}
이와 같이 의존하는 오브젝트를 new로 생성하는 것이 아니라 외부에서 넘겨받는 것을 의존성 주입이라고 한다.
TodoService 오브젝트를 생성할 때 ITodoPersistence 구현부, 정확히는 인터페이스를 넘겨줌으로써 의존성을 주입한다.
2) Setter을 이용한 의존성 주입, 서비스 코드
public class TodoService {
private fical ITodoPersistence persistence; // 인터페이스
public void setTodoService(ITodoPersistence persistence) {
this.persistence = persistence;
}
public static void main(String[] args) {
ItodoPersistence persistence = new FileTodoPersistence();
TodoService service = new TodoService();
service.setTodoPersistence(persistence);
}
}
의존성 주입 구현은 유닛 테스트에서 가짜 오브젝트, 즉 Mock 오브젝트를 주입하는 데도 유용.
3) 유닛 테스트에서 Mock 오브젝트 주입
@Test
public void test() {
ITodoPersistence persistence = new MockTodoPersistence();
TodoService service = new TodoService(persistence);
}
뭐가 좋은지 잘 모르겠음..^^ 천천히 배워보는 걸로ㅋ
아무튼 이런 의존성 주입을 전문적으로 해주는 것이 스프링 프레임워크다.