Dependency Injection (DI)은 객체 지향 프로그래밍에서 사용되는 디자인 패턴 중 하나로, 클래스 간의 결합도를 낮추고 코드의 유연성과 재사용성을 높이는데 도움을 준다. DI는 클래스 내부에서 직접적으로 객체를 생성하는 대신, 외부에서 생성된 객체(의존성)를 주입하는 방식으로 작동한다.

 

이 패턴의 주요 이점은 다음과 같다:

 

① 코드의 모듈성: 의존성 주입을 사용하면 클래스들이 서로 덜 의존하게 되므로, 코드의 모듈성이 향상된다.

② 유연성과 확장성: 클래스 간 결합도가 낮아지면, 기능 변경이나 확장이 더 쉽고 간단해진다.

③ 테스트 용이성: 의존성 주입을 사용하면, 테스트 시 의존성을 쉽게 대체하거나 모의 객체로 교체할 수 있어 테스트 용이성이 향상된다.

DI는 주로 생성자 주입, 세터 주입, 인터페이스 주입 등의 방식으로 구현할 수 있다. 프레임워크나 라이브러리를 통해 자동화된 의존성 주입을 사용할 수도 있다. 대표적인 예로 Java의 Spring 프레임워크, .NET의 ASP.NET Core, Python의 Flask-Injector 등이 있다.

 

예시코드


  1. MessageService Interface를 만든다.
public interface MessageService {
  String getMessage();
}
  1. `MessageService` 인터페이스를 구현한 `HelloMessageService` 클래스를 생성한다.
import org.springframework.stereotype.Service;

@Service
public class HelloMessageService implements MessageService {
  @Override
  public String getMessage() {
    return "Hello, Spring Boot!"
  }
}
  1. `MessageController` 클래스를 생성하고, `MessageService`를 의존성을 주입한다.

이때 @Autowired 사용한다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {
  private final MessageService messageService;
  
  @Autowired
  public MessageController(MessageService messageService) {
    this.messageService = messageService;
  }
  
  @GetMapping("/message")
  public String getMessage() {
    return messageService.getMessage();
  }
}

위 코드에서 `MessageController`의 생성자에 `@Autowired` 사용하여

`MessageService`의 구현체인 `HelloMessageService`를 자동으로 주입한다.

이렇게 하면 `MessageController`는 `MessageService`의 구체적인 구현에 대해 알 필요 없이 인터페이스를 통해 메서드를 호출할 수 있다. 이 방식은 코드의 결합도를 낮추고 유연성을 높이는 데 도움을 준다.

만약 MessageService 인터페이스의 구현체를 바꾸고 @Autowired에 되는 걸 바꾸고 싶다면,

1.일단 MessageService 인터페이스의 구현체를 하나 더 만든다.

import org.springframework.stereotype.Service;

@Service
public class GoodbyeMessageService implements MessageService {
  @Override
  public String getMessage() {
    return "Goodbye, Spring Boot!"
  }
  
}

2.MessageConfiguration 설정 클래스를 하나 만들어서 GoodbyeMessageService를 사용하도록 설정한다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MessageConfiguration {
  
  @Bean
  public MessageService messageService() {
    return new GoodbyeMessageService();
  }
}

위의 코드에서 `MessageConfiguration` 클래스를 사용해서

`MessageService` 빈을 `GoodbyeMessageService`의 인스턴스로 설정했다.

이제 `MessageController`에서 `MessageService`인터페이스의 구현체로

`GoodbyeMessageService`가 주입되어 사용된다.

+ Recent posts