[10분 테코톡] 모찌의 의존성 주입
ORIGINAL SOURCE ↗YouTube에서 보기 | 영상 길이: 8분 24초
요약
발표 소개 및 핵심 질문
우아한테크코스 7기 모찌의 발표. 목차는 Intro → DI → DIP → 마무리 순서로 진행된다.
발표 대상:
- DI, DIP를 처음 접하는 사람
- 두 용어의 차이를 명확히 정리하고 싶은 사람
- 우테코 4단계를 잘 마무리하고 싶은 사람
발표 시작 전 두 가지 질문을 제시하며 이 질문에 답하는 방식으로 발표가 전개된다.
- DI와 DIP, 뭐가 달라?
- 이걸 왜 4단계에서 다시 배울까?
DI — 의존성(Dependency)이란?
위키피디아에서 DI를 검색하면 “하나의 객체가 다른 객체의 의존성을 제공하는 테크닉”이라고 정의되어 있다. 하지만 발표자는 이 정의가 와닿지 않는다고 말하며, “의존성”과 “주입” 두 단어로 나눠서 직접 정의해보겠다고 한다.
의존성 — 예시로 이해하기
상황 설정: 개발자 행성이는 데모데이 D-1에 치명적인 버그를 발견했다. 밤을 새워 버그를 고쳐야 하는 상황에서 핫식스를 마시기로 했다. 이를 코드로 표현하면, 행성이 객체가 핫식스 객체를 주입받아 핫식스를 만들고, 핫식스를 통해 밤을 샌다.
의존성의 첫 번째 특징 발견 [02:20]: 집 앞 편의점에서 갑자기 핫식스를 팔지 않는다면 어떻게 될까? 행성이는 카페인 공급을 받지 못해 밤을 세우지 못하고, 버그를 고치지 못한 채 데모데이 때 방황하게 된다. 이 상황에서 발견하는 의존성의 첫 번째 특징:
A가 동작하기 위해서는 B가 필요하다 (행성이가 밤을 새우기 위해서는 핫식스가 필요하다)
의존성의 두 번째 특징 발견 [03:00]:
이번엔 핫식스 제조사가 전국적으로 카페인 용량을 증가시켰다. 그 결과 메서드명이 boostEnergy()에서 boostSuperEnergy()로 변경됐다. 그런데 이 변경이 행성이의 코드에도 영향을 미쳐 행성이 내부 코드도 같이 변경해야 하는 상황이 발생한다. 이로부터 발견하는 두 번째 특징:
B가 변경되면 A도 변경된다 (핫식스가 변경되면 행성이 코드도 변경된다)
의존성 최종 정의:
A가 동작하기 위해서는 B가 필요하고, B가 변경되면 A도 변경되어야 한다.
DI — 주입(Injection)이란?
[03:58] “주입”을 한국대백과사전에서 검색하면 두 가지 뜻이 나오는데, 그 중 첫 번째인 “흘러가도록 부어넣음” 에 집중한다. 즉 외부에서 내부로 부어넣는 것. 항아리에 액체를 붓는 것처럼 외부에서 내부로 무언가를 집어넣는 행위가 주입이다.
의존성 + 주입 = 의존성 주입 정의:
객체가 동작하기 위해 필요한 것들을 외부에서 집어넣어 주는 것
즉, 행성이가 스스로 핫식스를 만들어 쓰는 게 아니라, 외부에서 핫식스(또는 다른 음료)를 만들어 행성이에게 건네주는 구조가 의존성 주입이다.
DIP — 의존 관계 역전 원칙
[04:36] DI를 검색하면 항상 DIP가 함께 나오는데, 이 둘이 뭐가 다른지 늘 의문이었다고 발표자는 말한다. 다시 문제의 코드로 돌아가서 DIP의 필요성을 설명한다.
문제 상황: 행성이가 이번엔 핫식스 대신 얼박사를 마시고 싶다면 어떻게 될까? 현재 구조에서는 얼박사라는 새 클래스를 만들고, 행성이의 내부 코드를 직접 수정해야 한다. 이는:
- 변경에 불편하다 — 음료 종류가 바뀔 때마다 행성이 코드를 고쳐야 함
- 유지보수에 불편하다 — 코드가 구체적인 구현체에 강하게 결합됨
- 확장에 닫혀있다 — 새로운 음료를 추가할수록 내부 수정이 계속 필요함
[05:49] 이때 등장하는 것이 로버트 마틴(우테코 1단계 때 많이 보던 분)의 SOLID 원칙, 그 중 마지막 D — DIP(의존 관계 역전 원칙):
“추상화는 구체적인 사항에 의존해서는 안 된다. 구체적인 사항은 추상화에 의존해야 한다.”
DIP를 적용한 해결책 [06:12]:
행성이가 HotSix나 EolBaksa(구체 클래스)에 직접 의존하는 대신, EnergyDrink라는 인터페이스(추상화) 에 의존하도록 바꾼다. 코드 구조는 이렇게 바뀐다:
행성이 → EnergyDrink (인터페이스)
↑ ↑
HotSix EolBaksa (구체 구현체)
행성이는 이제 어떤 음료가 들어오는지 알 필요가 없다. 인터페이스만 알고 있으면 된다.
그럼 실제 협력은 어떻게? [07:14]: 외부(main)에서 핫식스 또는 얼박사 인스턴스를 만들어 행성이에게 주입한다. main이 둘의 협력 관계를 결정하고 만들어주는 것이다. 이것이 바로 IoC(Inversion of Control, 제어의 역전) — 객체가 스스로 의존성을 만들지 않고, 제어권을 외부로 넘기는 것이다. 이로 인해 설계가 유연해지고 재사용성이 높아진다.
DI / DIP / IoC 최종 정리
[07:38] 발표 처음에 던진 질문 “DI와 DIP가 뭐가 달라?”에 대한 답:
- DIP (Dependency Inversion Principle): 상위 수준 모듈이 하위 수준 구현이 아닌 추상화에 의존해야 한다는 설계 원칙
- IoC (Inversion of Control): DIP 원칙을 지키기 위해 객체의 제어권을 외부로 넘기는 개념
- DI (Dependency Injection): DIP를 구현하고 IoC를 실현하기 위한 구체적인 기법 — 의존성을 외부에서 주입하는 방식
정리하면 DIP → IoC → DI 순으로 원칙 → 개념 → 구현 방법의 관계다.
왜 우테코 4단계에서 다시 배울까?
[08:07] 발표자의 결론: DI를 통해 테스트와 유지보수를 편하게 만들어, 지금 만든 앱을 오랫동안 지속 가능하게 하려는 코치님들의 큰 그림이 있는 것 같다. 단순히 기능을 만드는 것을 넘어, 오래 살아있는 소프트웨어를 만드는 능력을 기르기 위한 것이다.
키워드
의존성-주입, DI, DIP, IoC, SOLID, 인터페이스, 추상화, 제어의역전, 테코톡, 우테코