📌 DI(Dependency Injection)
⭐ 개념
- 메인 모듈이 다른 하위 모듈에 직접 의존성을 주기보다는 중간에
의존성 주입자
가 이 부분을 가로채 메인모듈이 간접적
으로 의존성을 주입하는 방식이다.
- 의존성 주입을 할 때 DIP가 적용된다.
💡 의존한다
- A가 B에 의존한다 = A -> B
- B가 변하면 A에 영향을 미친다.
import java.util.*;
class B {
public void eat() {
System.out.println("B의 eat()함수");
}
}
class A {
public void eat() {
new B().eat();
}
}
public class main{
public static void main(String args[]) {
new A().eat();
}
}
⭐ 코드
💡 DI 미적용
import java.util.*;
class Backend {
public void writeJava() {
System.out.println("자바로 코딩중");
}
}
class Frontend {
public void writeJavascript() {
System.out.println("자바스크립트로 코딩중");
}
}
public class Project {
private final Backend backend;
private final Frontend frontend;
public Project(Backend backend, Frontend frontend) {
this.backend = backend;
this.frontend = frontend;
}
public void start() {
backend.writeJava();
frontend.writeJavascript();
}
public static void main(String args[]) {
Project pj = new Project(new Backend(), new Frontend());
pj.start();
}
}
💡 DI 적용
import java.util.*;
interface Developer {
void develop();
}
class Backend implements Developer {
@Override
public void develop() {
writeJava();
}
public void writeJava() {
System.out.println("자바로 코딩중");
}
}
class Frontend implements Developer {
@Override
public void develop() {
writeJavascript();
}
public void writeJavascript() {
System.out.println("자바스크립트로 코딩중");
}
}
public class Project {
private final List<Developer> developers;
public Project(List<Developer> developers) {
this.developers = developers;
}
public void start() {
developers.forEach(Developer::develop);
}
public static void main(String args[]) {
List<Developer> dev = new ArrayList<>();
dev.add(new Backend());
dev.add(new Frontend());
Project pj = new Project(dev);
pj.start();
}
}
⭐ 장/단점
💡 장점
- 코드의 재사용성, 유연성이 높아진다.
- 클래스간 결합도를낮출 수 있다.
- 유지보수가 쉬우며 테스트가 용이해진다.
- 의존성 방향이 좀 더 일관되어 코드추론이 쉬워진다.
💡 단점
- 모듈이 더 생기므로 복잡도가 증가한다.
- 주입된 객체들에 대한 코드 추론이 어렵다.
📌 DIP(Dependency Inversion Principle)
- 상위 모듈은 하위모듈에 의존해서는 안된다. 둘 다 추상클래스나 인터페이스에 의존해야 한다.
- 클라이언트(사용자)가 상속 관계로 이루어진 모듈을 가져다 사용할때, 하위 모듈을 직접 인스턴스를 가져다 쓰지 말라는 뜻이다. 왜냐하면 그렇게 할 경우, 하위 모듈의 구체적인 내용에 클라이언트가 의존하게 되어 하위 모듈에 변화가 있을 때마다 클라이언트나 상위 모듈의 코드를 자주 수정해야 되기 때문이다.
- 변화하기 쉬운 것에 의존하기보다는, 변화하지 않는 것에 의존하라는 원칙