본문 바로가기
Programming/Springboot

DI(Dependency Injection) 의존성 주입이란?

by 우공80 2022. 8. 19.
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

댓글