의존성 주입(Dependency Injection)

김말이·2023년 7월 30일
0

✏️ 의존성

A가 B를 의존한다
➡️의존 대상 B가 변하면 그것이 A에 영향을 미친다.

  • B의 기능이 추가 또는 변겨되거나 형식이 바뀌게 되면 그 영향이 A에 미치게 되는 것을 말한다.

❗의존성 주입

💡의존성 주입은 필요한 객체를 직접 생성하거나 찾지 않고, 외부에서 필요한 객체를 받아 사용하는 것이다.

이를 통해 객체간의 결합도를 줄이고 코드의 재활용성을 높여준다.

예시

이 개발 블로그에 글을 쓰는 상황에 대해 생각해 보았다.
개발 공부 기록 목적의 블로그를 만들고, 여기에 안드로이드 앱 개발 관련 포스트를 작성해 보자.

1️⃣단순 의존 관계

"개발 공부 글을 올려야지!"

블로그에 올리는 포스트에 따라 다른 메소드들을 필요로 하지 않기 때문에, AndroidPost()라는 객체를 만들어준 후 Blog()가 이를 의존하게 하면 된다.

// Blog 객체 생성
Blog blog = new Blog();
// 새로운 글 작성하기
blog.getNewPost();

class Blog {
	
    private AndroidPost androidPost;

    public Blog() {
    	// 블로그가 AndroidPost()에 의존한다
        this.androidPost = new AndroidPost()
    }
    // 새로운 글을 작성할 때 사용할 함수
    public getNewPost() {
    	// AndroidPost에 있는 메소드를 사용한다
        // Blog가 AndroidPost에 의존하고 있다
    	androidPost.writePost();
    }
}

class AndroidPost {
	public Post writePost() {
    	return workbook;
    }
}

2️⃣인터페이스로 추상화하기

"올리는 주제에 따라 기능을 다르게 하고 싶어!"

블로그에 글이 많아질수록, 포스트의 주제에 따라 글 구성과 설정을 다르게 하고 싶어진다. 이를 관리하기 위해서, 블로그에 카테고리를 만들어 설정을 다르게 할 수 있도록 해보자.

Blog blog = new Blog();
blog.getNewPost();

// Category 인터페이스 -주제- 를 만들어 준다
interface Category{
	// 카테고리마다 있어야 할 메소드들
	Post writePost()
    // 비공개 설정, 양식 설정 등등...
}

class Blog {

    private Category category;

    public Blog() {
        this.category = new AndroidPost()
        // 백엔드 관련 코딩 기록을 남기고 싶다면, 위 코드 대신 아래 코드를 활성화
        // this.category = new ServerCoding()
    }
    
    public getNewPost() {
    	category.writePost();
    }
}

class AndroidStudy implements Category {
	public Post writePost() {
    	return workbook;
    }
}
class ServerCoding implements Category {
	public Post writePost() {
    	return code; // 주제에 따라 다른 Post 내용 구성을 업로드한다
    }
}

3️⃣의존성을 주입했을 때

코드를 계속 수정하는 것이 불편하다!

인터페이스를 통해서 기존 Blog-AndroidPost 클래스 간의 결합도를 낮추고 더 다양한 의존 관계를 맺을 수 있었지만, 아직 Blog 클래스 안에서 내부적으로 어떤 카테고리의 글을 작성할지에 대해 직접 지정해주고 있다. 더욱 객체 지향적으로 코드를 작성해야 하기 때문에, Blog 안의 클래스를 건드리는 것은 좋은 방법이 아니다.
Blog 객체가 생성되는 외부의 코드에서 카테고리를 지정해 주는 방법에 대해 생각해 보자.

// 의존성 주입
// 안드로이드 스터디 내용을 작성할 것이라고 외부에서 지정해 주었다
Blog blog = new Blog(new AndroidStudy());
blog.getNewPost();

interface Category{
	Post writePost()
}
class Blog {
	private Category category;
    
    // 블로그 클래스가 생성될 때, 카테고리가 지정된다
    public Blog (Category category) {
    	this.category = category;
    }
    
    public getNewPost() {
    	uploadPost.writePost();
    }
}
class AndroidStudy implements Category {
	public Post writePost() {
    	return workbook();
    }
}
class ServerCoding implements Category {
	public Post writePost() {
    	return code;
    }
}

DI(의존성 주입)을 진행한 모습이다. 이는 생성자를 이용하여 DI를 구현한 예시인데, Blog 클래스의 생성자에서 변수를 통해 카테고리를 지정하며 클래스 내부 코드를 굳이 이해할 필요 없이 외부에서 포스트 내용을 결정하고 주입하였다.

Spring에서의 예시

DI는 Spring에서 많이 사용된다. 지금까지는 단순히 DI에 대한 이해를 해 보았다면, 아래에서는 Spring을 통한 DI 예시를 살펴보며 실전 사용에 대한 파악을 해 보겠다.

1️⃣생성자 주입

@Component
public class OrderServiceImpl implements OrderService {

 	private final MemberRepository memberRepository
	private final DiscountPolicy discountPolicy;
 
 @Autowired
 public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy 
	discountPolicy) {
            
	this.memberRepository = memberRepository;
	this.discountPolicy = discountPolicy;
    
 	}
}
  • 생성자를 통해서 의존 관계를 주입받는다.
  • 생성자 호출시점에 딱 1번만 호출된다.
  • 불변, 필수 의존관계에 사용한다.

2️⃣수정자 주입

@Component
public class OrderServiceImpl implements OrderService {
	private MemberRepository memberRepository;
	private DiscountPolicy discountPolicy;
    
 @Autowired
 public void setMemberRepository(MemberRepository memberRepository) {
 	this.memberRepository = memberRepository;
 }
 
 @Autowired
 public void setDiscountPolicy(DiscountPolicy discountPolicy) {
	 this.discountPolicy = discountPolicy;
 }
}
  • Setter라고 하는 필드의 값을 변경하는 메소드를 이용하여 의존관계를 주입한다.

❓의존성 주입이 필요한 이유

  • Unit Test가 용이해진다.
  • 코드의 재사용성, 유연성이 높아진다.
    • 하나의 작업만 수행하는 작은 객체는 많은 상황에서 재결합할 수 있음
    • 확장성을 가짐
  • 객체 간의 의존성을 줄인다.
    • 결합도를 낮추면서 유연한 코드를 작성할 수 있다.
    • 한 클래스를 수정했을 때 다른 클래스도 수정해야 하는 상황을 막아줌

참고

의존성 주입이란 무엇이며 왜 필요한가?

profile
공부해서 남주자

1개의 댓글

comment-user-thumbnail
2023년 7월 30일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기