728x90
DI(Dependency Injection)
아래 예제는 url을 base64로 encoding 하거나 url로 encoding 하는 예제입니다.(생성자를 이용)
여기에서 Encoder는 UrlEncoder와 Base64Encoder에 의존하고 있습니다. 그리고 다양한 Encoding에 의존 받을 수 있게 구현하기 위해 IEncoder 인터페이스로 추상화를 했습니다.
그렇게 정리된 것이 아래 코드입니다.
하지만, 이 경우에는 Encoder 내부에서 의존관계를 가지고 있습니다.
공통되는 부분을 잘 추상화하여 정리하였지만, 내부적인 의존관계로 인해 Base64 또는 Url Encoding로 변경을 위해서는 소스의 본질적인 부분을 수정하게 됩니다.
package com.company.ioc;
import java.net.URLEncoder;
import java.util.Base64;
import java.io.UnsupportedEncodingException;
public class Encoder {
private IEncoder iEncoder; //interface 를 가지고 있다가
/*생성자에서 필요에 따라 Base64 or Url Encoding을 한다.
만약 2개를 번갈아가면서 테스트 해야 한다면, 테스트하는 부분이 아니라
메인 로직을 건드리게 되어 비효율적이다*/
public Encoder() { //Encoder 내부의 의존관계
//this.iEncoder = new Base64Encoder(); //이쪽을 썼다가
this.iEncoder = new UrlEncoder(); //이쪽을 썼다가
}
public String encode(String message) {
return iEncoder.encode(message);
}
}
public class UrlEncoder implements IEncoder{
public String encode(String message) {
try {
return URLEncoder.encode(message,"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
public class Base64Encoder implements IEncoder{
@Override
public String encode(String message) {
// TODO Auto-generated method stub
return Base64.getEncoder().encodeToString(message.getBytes());
}
}
public interface IEncoder {
String encode(String message);
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "www.naver.com/books/it?page=10&size=20&name=spring-boot";
//공통화함
Encoder encoder = new Encoder();
String result = encoder.encode(url);
System.out.println(result);
}
}
이렇게 이런 내부적인 의존관계가 아닌 외부에서 의존관계를 결정하고 주입하는 것이 DI(Dependency Injection)입니다.
public class Encoder {
private IEncoder iEncoder; //interface 를 가지고 있다가
//생성자에서 iEncoder를 주입받는다.
public Encoder(IEncoder iEncoder) {
//this.iEncoder = new Base64Encoder();
//this.iEncoder = new UrlEncoder();
this.iEncoder = iEncoder;
}
public String encode(String message) {
return iEncoder.encode(message);
}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "www.naver.com/books/it?page=10&size=20&name=spring-boot";
//Encoder 외부에서 객체를 주입받습니다.
Encoder encoder = new Encoder(new Base64Encoder());
//Encoder encoder = new Encoder(new UrlEncoder());
//Base32Encoder()가 필요하면 Base32Encoder()만 만들면 사용할 수 있다.
String result = encoder.encode(url);
System.out.println(result);
}
}
이렇게 외부에서 객체를 주입함으로서 얻는 DI의 장점은 다음과 같습니다.
- 의존성으로부터 격리시켜 코드 테스트에 용이하다.
- DI를 통하여, 불가능한 상황을 Mock와 같은 기술을 통하여, 안정적으로 테스트 가능하다.
- 코드를 확장하거나 변경할 때 영향을 최소화 한다.(추상황)
- 순환참조를 막을 수 있다.
참고자료
의존관계 주입(Dependency Injection) 쉽게 이해하기패스트캠퍼스 - Java & SpringBoot로 시작하는 웹 프로그래밍
728x90
'Programming > Springboot' 카테고리의 다른 글
Gradle 프로젝트를 Maven프로젝트로 Convert 하는 방법(for Eclipse) (0) | 2022.08.29 |
---|---|
object-mapper 실습 (0) | 2022.08.17 |
댓글