DI란
- Dependecy Injection을 알기 전에 Object Dependecies를 아는 것이 중요할 거 같다.
Object Dependencies란
- 현재 객체가 다른 객체를 참조하고 있다면, 현재 객체는 다른 객체에 의존성을 가진다.
public class AnimalHospital{
private AnimalType animal;
public AnimalHospital(){
this.animal = new Bird();
}
}
- AnimalHospital 객체는 AnimalType 객체에 의존성을 가진다.
- AnimalHospital 객체는 AnimalType을 생성자에서 직접 제어한다. 그렇기 때문에 두 객체간의 tight coupling이 생긴다. AnimalType 객체를 변경하면, AnimalHospital 객체도 변하게 된다.
- 이처럼, 하나의 객체를 바꾸면, 그 객체와 의존성을 가진 다른 모듈까지 변경되어야 한다는 문제점이 존재한다.
그럼 의존성 주입은?
- 위 예제에서는 AnimalHospital에서 어떤 AnimalType을 가질지 직접 정하고, 할당했다.
- 의존성 주입은 내부에서 의존관계를 결정하는 것이 아닌, 외부에서 의존관계를 결정하고 주입해주는 것이다.
- 생성자 이용
public class AnimalHospital{
private AnimalType animal;
public AnimalHospital(AnimalType animalType){
this.animal = animalType;
}
}
class Doctor{
private AnimalHospital doctor = new AnimalHospital(new Bird());
public void changeAnimalType() {
doctor = new AnimalHospital(new Dog());
}
}
public class AnimalHospital{
private AnimalType animal = new Bird();
public void setAnimalType(AnimalType animalType){
this.animal = animalType;
}
}
class Doctor{
private AnimalHospital doctor = new AnimalHospital();
public void changeAnimalType() {
doctor.setAnimalType(new Dog());
}
}
DI 장점은?
- 의존성이 줄어든다.
- 의존한다는 것의 의미는 의존대상의 변화에 대응하기 어렵다. 대상이 변화한다면, 이에 맞게 수정을 해야한다. 의존성 주입을 받으면, 대상이 변하여도, 구현 자체를 수정할 일이 없거나 줄어들게됨.
- 재사용성이 높은 코드가 된다.
- AnimalHospital 내부에서만 사용된 AnimalType을 별도로 구분하여 구현하여, 다른 클래스에서도 재사용이 가능하다.
- 테스트하기 좋은 코드가 된다.
- AnimalHospital과 AnimalType을 분리하여, 테스트를 진행할 수 있다. Unit Test가 가능해진다.
Reference