컴퓨터 공학 & 통신

[개념 정리] 의존성 주입(DI), 의존 관계 역전 원칙(DIP)

왈왈디 2023. 7. 4. 15:24
728x90

의존성

배경 지식으로 의존성의 의미를 살펴보자.

A가 B에 의존한다는 것은 B의 변화가 A에 영향을 미치는 것을 의미한다.

기호로는 A → B 로 표시한다

 

의존성 주입(DI, Dependecy Injection)

의존성 주입이란 메인 모듈(main module)이 직접 다른 하위 모듈에 의존성을 부여하지 않고,

중간에 의존성 주입자(dependency injector)를 두어

메인 모듈이 간접적으로 의존성을 주입하는 방식이다.

 

직접 의존 VS 의존성 주입자 사용

의존성 주입을 통해 메인 모듈과 하위 모듈 간의존성을 느슨하게 만들 수 있으며,

모듈을 쉽게 교체 가능한 구조로 만든다.

 

DI를 적용하지 않은 예시

자바로 DI를 적용하지 않은 코드 예시를 살펴보자.

프로젝트라는 클래스가 있고, 프론트엔드 개발자, 백엔드 개발자라는 클래스가 있는 상황이다.

import java.util.*;

class BackendDeveloper {
	public void writeJava() {
		System.out.println("자바를 사용하는 백엔드 개발자");
	}
}

class FrontEndDeveloper {
	public void writeJavascript() {
		System.out.println("자바스크립트를 사용하는 프론트엔드 개발자");
	}
}

public class Project {
	private final BackendDeveloper backendDeveloper;
	private final FrontEndDeveloper frontEndDeveloper;
    
	public Project(BackendDeveloper backendDeveloper, FrontEndDeveloper frontEndDeveloper) {
		this.backendDeveloper = backendDeveloper;
		this.frontEndDeveloper = frontEndDeveloper;
	}

	public void implement() {
		backendDeveloper.writeJava();
		frontEndDeveloper.writeJavascript();
	}
    
	public static void main(String args[]) {
		Project a = new Project(new BackendDeveloper(), new FrontEndDeveloper());
		a.implement();
	}
}

 

DI를 적용한 예시

DI를 적용하게 되면, 여러 개발자를 추가할 수 있고,

백엔드 개발자와 프론트엔드 개발자 외의 다른 개발자로 쉽게 교체가 가능한 구조가 된다.

또한 의존성이 역전된다.

DI를 적용하면 의존 관계 역전 원칙(Dependency Inversion Principle)이 적용됨을 볼 수 있다.

interface Developer {
	void develop();
}

class BackendDeveloper implements Developer {
	@Override
	public void develop() {
		writeJava();
	}
    
	public void writeJava() {
		System.out.println("자바 개발자");
	}
}

class FrontendDeveloper 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 implement() {
		developers.forEach(Developer::develop);
	}
    
	public static void main(String args[]) {
		List<Developer> dev = new ArrayList<>();
		dev.add(new BackendDeveloper());
		dev.add(new FrontendDeveloper());
		Project a = new Project(dev);
		a.implement();
	}
}

 

의존 관계 역전 원칙(DIP, Dependency Inversion Principle)

의존성 주입이 이루어질 때는 의존 관계 역전 원칙이 적용된다.

이는 아래 2가지 규칙을 지키는 상태를 말한다.

  1. 상위 모듈은 하위 모듈에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다.
  2. 추상화는 세부 사항에 의존해서는 안 된다. 세부 사항은 추상화에 따라 달라져야 한다.

 

의존성 주입의 장점

  1. 외부에서 모듈을 생성하여 집어 넣는 구조가 되기 때문에, 모듈의 교체가 쉽다. (e.g., dev.add(new BackendDeveloper()) )
  2. 단위 테스트마이그레이션*이 쉬워진다.
  3. 애플리케이션의 의존성 방향이 일관되어 코드 추론이 쉬워진다.

 

의존성 주입의 단점

  1. 결국 모듈이 더 생기는 것이므로 복잡도가 증가하고, 코스트가 늘어난다.
  2. 종속성 주입 자체가 컴파일이 아닌 런타임에서 일어나기 때문에, 컴파일 과정에서 종속성 주입에 관한 에러를 잡기 어려워질 수 있다.

 

참고: inflearn 강의 'CS 지식의 정석 - 큰돌'

728x90