본문 바로가기
소프트웨어공학/SW 설계 원칙

[SW 설계 원칙] 의존성 주입(DI, Dependency Injection) 쉽게 이해하기(w/Python)

by 클레어몬트 2025. 3. 13.

https://claremont.tistory.com/entry/SW-%EC%84%A4%EA%B3%84-%EC%9B%90%EC%B9%99-SOLID-%EC%9B%90%EC%B9%99%EA%B3%BC-%EA%B7%B8-%EC%A7%84%EC%A0%95%ED%95%9C-%EC%9D%98%EB%AF%B8

 

[SW 설계 원칙] SOLID 원칙과 그 진정한 의미

ㅁSOLID 원칙: 객체지향 설계의 핵심 원칙 소프트웨어 개발에서 유지보수성과 확장성을 높이기 위해서는 올바른 설계 원칙을 따르는 것이 중요하다. SOLID 원칙은 이러한 객체지향 설계를 효과적

claremont.tistory.com

 

 

 

괜히 쫄 거 없다!

정말 간단한 개념이다

예제를 통해 의존성 주입이 무엇인지 알아볼 거고, 언어는 제일 가독성이 좋은 파이썬을 이용하겠다 :]

 

ㅁ의존성 주입(DI, Dependency Injection): 객체 간의 의존성을 직접 생성하지 않고 외부에서 주입하는 설계 패턴

인젝션!


즉, 객체가 직접 다른 객체를 생성하는 것이 아니라 필요한 객체를 외부에서 받아서 사용하는 방식이다

 

 

먼저, DI가 적용이 안 된 예시 코드를 보자

class Database:
    def connect(self):
        return "DB 연결됨"

class Service:
    def __init__(self):
        self.db = Database() # ❌ Service가 직접 Database를 생성 (강한 결합)
    
    def get_data(self):
        return self.db.connect()

service = Service()
print(service.get_data()) # DB 연결됨

 

🔴 문제점:

  • Service 클래스가 Database에 강하게 의존 → Database를 교체하기 어려움
  • 테스트 시 Database를 Mock으로 대체하기 어려움
  • Database의 변경이 Service에도 영향을 줌

 

 

그렇다면 DI를 적용시킨 코드는?

class Database:
    def connect(self):
        return "DB 연결됨"

class Service:
    def __init__(self, db: Database): # ✅ 의존성을 외부에서 주입 (DI)
        self.db = db
    
    def get_data(self):
        return self.db.connect()

db_instance = Database()
service = Service(db_instance) # ✅ Database 인스턴스를 외부에서 주입
print(service.get_data()) # DB 연결됨

 

✔️ DI를 적용하니, Service가 Database에 직접 의존하지 않음
✔️ 테스트할 때 Mock 객체를 쉽게 주입 가능
✔️ 유지보수가 용이해지고, 코드 재사용성이 높아짐

 

 

 

 

[DI를 사용하는 이유]

🔹 코드의 결합도를 낮춰 유지보수성을 높임
🔹 객체 간의 의존성을 명확하게 관리
🔹 테스트 용이성 증가 (Mocking이 쉬움)
🔹 코드 재사용성이 높아지고, 변경에 유연

 

 

 

 

※ DI 개념이 중요하듯, 프레임워크들에서는 DI 메서드들을 다 지원한다

e.g. FastAPI에서는 Depends()를 활용하여 DI를 구현
e.g. Spring에서는 @Autowired 애노테이션을 통해 DI 적용