노트

의존성 역전 원칙

Dependency Inversion Principle

설계#architecture · 연결된 개념 11개

쉽게 말하면

의존성 역전 원칙은 리모컨을 특정 회사 건전지가 아니라 'AA 규격'에 맞춰 만드는 것과 같아요. 업무 규칙은 규격에만 기대니까, 어느 회사 건전지든 테스트용 가짜든 바꿔 끼울 수 있어요.

비유가 깨지는 곳 건전지 규격은 만드는 쪽이 정하지만, 코드의 추상화는 쓰는 쪽인 고수준 모듈의 필요에 맞춰 정해요. 저수준 라이브러리 API를 그대로 베낀 인터페이스는 역전이 아니에요.

고수준 모듈(업무 규칙)이 저수준 모듈(데이터베이스(DB), HTTP(Hypertext Transfer Protocol) 클라이언트 같은 세부 구현)에 직접 의존하지 않고, 둘 다 추상화에 의존해야 한다는 원칙. 의존 방향이 "업무 → 세부"에서 "세부 → 추상화 ← 업무"로 뒤집힌다.

from abc import ABC, abstractmethod
 
class Database(ABC):
    @abstractmethod
    def save(self, data): ...
 
class UserService:
    def __init__(self, db: Database):  # 구체 클래스가 아니라 추상화에 의존
        self.db = db
  • DB를 바꾸거나 테스트용 가짜를 넣을 때 UserService를 고치지 않아도 된다
  • 추상화는 고수준 쪽 필요에 맞춰 정의한다. 저수준 라이브러리의 API(Application Programming Interface)를 그대로 베낀 인터페이스는 역전이 아니다
  • 파이썬은 ABC(Abstract Base Class)나 프로토콜(Protocol), TypeScript는 인터페이스와 구조적 타이핑으로 표현한다

원칙과 기법

DIP(Dependency Inversion Principle)는 "무엇에 의존해야 하는가"라는 원칙이고, 의존성 주입(Dependency Injection)은 그 구현을 바깥에서 넣어 주는 기법이다. 주입 없이도 DIP를 지킬 수 있고, 주입을 써도 구체 클래스를 주입하면 DIP는 아니다.

React에서

  • Context로 주입: 컴포넌트가 axios를 직접 import하지 않고 HttpClient 같은 추상화를 Context에서 받는다. 테스트에서는 가짜 클라이언트를 Provider로 넣는다(MSW로 API 모킹도 다른 방식의 대안)
  • Props·children 합성: 버튼이 특정 아이콘 컴포넌트를 import하는 대신 icon prop으로 받는다(컴파운드 컴포넌트 패턴)

SOLID 원칙의 D이고, React로 보는 SOLID에 React 쪽 예가 더 있다. 과하면 구현이 하나뿐인 인터페이스만 늘어나니 교체나 테스트 필요가 실제로 있을 때 쓴다(YAGNI).

출처: Laws of Software Engineering: SOLID Principles

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 리스코프 치환 원칙

    부모 타입이 쓰이는 자리에 자식 타입을 넣어도 프로그램이 깨지지 않아야 한다는 원칙. 상속이 컴파일된다는 것만으로는 부족하고, 부모를 기대한 코드가 자식을 받아도 기대한 대로 동작해야 한다.

  • 집단 코드 소유

    코드의 주인을 개인으로 두지 않고 팀 전체가 코드베이스 전체를 소유해, 누구나 필요한 곳을 고칠 수 있게 하는 XP 실천법.

  • 상속보다 위임

    "클래스 상속보다 객체 합성(위임)을 써라"는 원칙과, 상속 관계를 위임으로 바꾸는 두 리팩터링. 상속을 쓰지 말라는 뜻이 아니라 과용에 대한 반작용으로 나온 말이다.

  • NestJS

    NestJS는 TypeScript를 전제로 모듈·의존성 주입(Dependency Injection, DI)·데코레이터(decorator) 구조를 제공하는 Node.js 서버 프레임워크다. 2017년 Kamil Myśliwiec가 만들었고, 구조를 강제하는 방식 때문에 흔히 "Node.js의 Spring"이라 불린다.

  • 심플 디자인

    켄트 벡이 XP(Extreme Programming)에서 제시한 단순한 설계의 네 가지 규칙. 우선순위 순으로 ① 모든 테스트를 통과하고 ② 의도를 드러내고 ③ 중복이 없고 ④ 요소가 가장 적다. 마틴 파울러가 이렇게 정리한 형태가 널리 쓰인다.

보기 옵션