오늘 뭐했냐/개발에 대한 주저리

23.09.26 의존성 주입(Dependency Injection, DI)

스스로에게 2023. 9. 26. 16:33

 기존에도 찾아봤던 내용이지만 그 때는 이해하기 힘들었다. 대부분 스프링에 대한 내용만 있었고, 나중에 다시 공부할 일이 있을거란 생각으로 가볍게 보고 넘어갔는데 이번에 Nest.JS 강의를 보면서 의문이 들어서 조금 더 끈질기게 찾아보고 이해하려고 하다보니 조금은 알 것 같아서 찾아본 내용을 정리하려고 한다. 

의존성 주입

  • 의존성 (Dependency): 의존성은 한 객체가 다른 객체에 의존하는 상황이다.
  • 주입 (Injection): 의존성을 생성자, 메서드 매개변수, 또는 속성으로 받아서 사용한다. 이를 통해 객체는 직접 의존성을 생성하지 않고 외부로부터 주입 받게 된다.

 

의존성 주입을 사용하는 이유 

 

  1. 결합도 감소(Decoupling): 객체 간의 결합도를 낮추어 코드의 변경이나 유지 보수가 더 쉬워진다.
  2. 유연성(Flexibility): 객체가 직접 의존성을 생성하지 않으므로 다른 종류의 의존성을 주입함으로써 동일한 객체를 다양한 상황에 재사용할 수 있다.
  3. 테스트 용이성(Testability): 테스트할 때 모의(Mock) 객체 또는 가짜(Fake) 객체를 주입하여 의존성을 제어할 수 있습니다. 이를 통해 단위 테스트와 모의 객체(Mocking)를 사용한 테스트를 수행할 수 있다.

 

사용 예시

// EmailService.js - 의존성 제공자 (Dependency Provider)
class EmailService {
  sendEmail(to, subject, body) {
    // 이메일 보내는 로직
    console.log(`Email sent to ${to}: ${subject}`);
  }
}

// UserService.js - 의존성 주입
class UserService {
  constructor(emailService) {
    this.emailService = emailService; // EmailService를 주입받음
  }

  registerUser(user) {
    // 사용자 등록 로직
    console.log(`User registered: ${user}`);

    // 이메일 서비스를 사용하여 이메일 보내기
    this.emailService.sendEmail(user.email, 'Welcome!', 'Welcome to our platform.');
  }
}

// main.js
const EmailService = require('./EmailService');
const UserService = require('./UserService');

const emailService = new EmailService();
const userService = new UserService(emailService); // 의존성 주입

const newUser = {
  name: 'John',
  email: 'john@example.com'
};

userService.registerUser(newUser);

 

 유저 서비스에서 이메일 서비스를 구현하기 위해서 직접 만든 것이 아니라 이메일 서비스를 따로 만들었으며 의존성 주입을 통해 사용하고 있다. 그래서 이메일을 사용하여 기능을 추가할 수도 있고 유저도 이메일이 필요 없거나 다른 기능을 추가할 때 서로 영향을 안받을 수 있다. 지금은 코드가 간단하지만 만약에 이메일의 코드가 복잡할 때 따로 분리하지 않으면 코드 수정과 재사용이 매우 불편해질 것이다. 

 

다시 사용하기 위해 복붙 하거나 확장 혹은 삭제할 때 코드를 수정하면서 실수할 가능성이 높으니까.