DI, DIP

DEV_HOYA·2023년 10월 19일
0

CS

목록 보기
15/55
post-thumbnail

📌 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() { // 1. 여기가 수정되면 3도 수정되어야함
		System.out.println("자바로 코딩중");
	}
}
class Frontend {
	public void writeJavascript() { // 2. 여기가 수정되면 4도 수정되어야함 
		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(); // 3
		frontend.writeJavascript(); // 4
	}
	public static void main(String args[]) {
		Project pj = new Project(new Backend(), new Frontend());
		pj.start();
	}
}

// Backend, Frontend가 변하면 Project에 영향을 미친다.
// Project => Backend, Frontend

💡 DI 적용

import java.util.*;
interface Developer {
	void develop(); // 5. 여기가 수정되면 6, 7, 8에 영향을 미침
}
class Backend implements Developer {
	@Override
	public void develop() { // 6
		writeJava(); // 2
	}
	public void writeJava() { // 1. 이 메소드명이 변하면 -> 2가 수정됨
		System.out.println("자바로 코딩중");
	}
}
class Frontend implements Developer {
	@Override
	public void develop() { // 7
		writeJavascript(); // 4
	}
	public void writeJavascript() { // 3. 이 메소드명이 변하면 -> 4가 수정됨
		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); // 8
	}
	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();
	}
}
// Backend와 Frontend가 Project에 영향을 미치지않는다.
// Developer클래스가 변경되면 Backend와 Frontend, Project에 영향을 미친다.
// 즉, Backend, Frontend, Project => Developer
// 의존의 화살표 방향이 역전된것을 볼수 있다.
// DIP(Dependency Inversion Principle)이 적용됨

⭐ 장/단점

💡 장점

  • 코드의 재사용성, 유연성이 높아진다.
  • 클래스간 결합도를낮출 수 있다.
  • 유지보수가 쉬우며 테스트가 용이해진다.
  • 의존성 방향이 좀 더 일관되어 코드추론이 쉬워진다.

💡 단점

  • 모듈이 더 생기므로 복잡도가 증가한다.
  • 주입된 객체들에 대한 코드 추론이 어렵다.

📌 DIP(Dependency Inversion Principle)

  • 상위 모듈은 하위모듈에 의존해서는 안된다. 둘 다 추상클래스나 인터페이스에 의존해야 한다.
  • 클라이언트(사용자)가 상속 관계로 이루어진 모듈을 가져다 사용할때, 하위 모듈을 직접 인스턴스를 가져다 쓰지 말라는 뜻이다. 왜냐하면 그렇게 할 경우, 하위 모듈의 구체적인 내용에 클라이언트가 의존하게 되어 하위 모듈에 변화가 있을 때마다 클라이언트나 상위 모듈의 코드를 자주 수정해야 되기 때문이다.
  • 변화하기 쉬운 것에 의존하기보다는, 변화하지 않는 것에 의존하라는 원칙

0개의 댓글