의존관계
의존관계 어떻게 설명할 수 있을까?
A클래스가 객체를 만들기 위하여 B클래스를 필요로 할 때,
이 때 B는 A의 의존대상이 된다고 할 수 있다.
한 가지 예를 들어보자.
컴퓨터를 구성하기 위해서는 cpu, 램, 하드드라이브, 그래픽카드등 부품들이 필요하다.
이런 각 각의 부품들은 컴퓨터의 dependency가 되는 것이다.
왜냐하면 컴퓨터는 위의 각 부품들에 의존하기 때문이다.
(위의 부품들이 없으면 안 됨)
이것을 코드로 짠 것은 아래와 같다.
public class Computer {
private Ram ram = new Ram(64);
private HardDrive hardDrive = new HardDrive(1024);
}
class Ram {
Integer ram;
public Ram(Integer ram) {
this.ram = ram;
}
}
class HardDrive {
Integer value;
public HardDrive(Integer hardDrive) {
this.value = hardDrive;
}
}
여기서 하드드라이브 혹은 다른 부품들을 변경하면 어떻게 될까?
모든 컴퓨터에 대해 변경이 될 것이다.
즉 지금의 코드는 부품이 바뀌게 될 때마다 코드를 변경해주어야 하는 불편함이 있는 것이다.
(이것을 다른 말로는 '강결합' 이라고도 할 수 있다.)
이러한 의존도를 약하게 하기 위하여 외부에서 의존관계가 있는 대상을 가져오는 것을
Dependency Injection 이라고 한다.
Dependency Injection
그럼 Computer 클래스에서 각 부품들에 대한 객체를 내부에서 직접 생성하지 않고 어떻게 해결할 수 있을까?
바로 외부에서 생성하여 전달받는 것이다. (이것이 의존성 주입)
두 가지 방법이 있다.
생성자를 이용한 주입
public class Computer {
private HardDrive hd;
private Ram ram;
public Computer(Ram ram, HardDrive hd) {
this.ram = ram;
this.hd = hd;
}
Computer computer = new Computer(new Ram(32), new HardDrive(1024));
Computer computer2 = new Computer(new Ram(64), new HardDrive(1024));
}
객체 내부에서 직접 생성하지 않고, 외부에서 생성자를 이용하여 주입하게 되면
각 컴퓨터 인스턴스에 서로 다른 구성요소를 제공할 수 있다.
setter 메소드를 이용한 주입
public class Computer {
private HardDrive hd;
private Ram r;
Computer computer(Ram ram, HardDrive hd) {
Computer computer = new Computer();
computer.setRam(ram);
computer.setHardDrive(hd);
return computer;
}
public void setRam(Ram ram) {
this.r = ram;
}
public void setHardDrive(HardDrive hardDrive) {
this.hd = hardDrive;
}
}
그래서 DI를 사용하는 이유가 뭔데?