주녁, DevNote
article thumbnail

지적과 댓글은 언제나 환영합니다!



의존성 주입이란?

 

스프링에서 지원하는 핵심 프로그래밍 모델 중 하나로

말 그대로 의존관계를 외부에서 결정해주는 디자인 패턴이다.



의존관계?

 

의존관계는 쉽게 이야기하자면

한 쪽이 변경되면 다른 한쪽도 변경되는 관계로 말할 수 있다.

    public class Customer{ // 초기모델
        private final int id; // 고유 ID
        private final String grade; // 회원 등급
        private final DiscountPolicy discountPolicy; // 할인정책
    }

    public class Customer{ // 변경 후 모델
        private final int id;
        private final String grade;
        private final VipDiscountPolicy vipPolicy; // VIP 할인정책으로 변경
    }

고객마다 할인정책을 정의해준 초기 모델에서

VIP 고객전용으로 할인정책을 변경하고 싶다면

생성자, Getter, Setter 등을 모두 수정해야 한다.

(이미 다른 서비스에서도 할인율을 사용하고 있다면 더 많은 수정이 필요하다)

 

이러한 관계를 Customer와 DiscountPolicy는 의존관계에 있다고 할 수 있다.

 

하지만, 회원 등급은 처음부터 VIP가 아닐텐데, 나중에 결정할 수는 없는걸까?

= 의존성을 최대한 나중에 결정할 순 없을까?



외부에서 결정하는 의존성

 

할인 정책의 행동은 이미 알고있다. 할인해주는 행동이다.

VIP 할인 정책의 행동은 무엇일까? 역시 할인이다.

    discountPolicy.discount();

    vipPolicy.discount();



각 할인 정책은 같은 행동을 하기 때문에 interface로 묶을 수 있다.

    public interface discountPolicy{ // 할인 정책 인터페이스는
        public double discount(); // 할인을 한다.
    }

    public class normalPolicy implementation discountPolicy{
        public double discount(){ return 0.15; } // 할인율 15
    }

    public class vipPolicy implementation discountPolicy{
        public double discount(){ return 0.30; } // 할인율 30
    }



이런 식으로 interface를 통해 정의하게 되면

아래와 같이 의존관계를 설정할 수 있다.

이를 생성자 주입 방식이라고 하며, Spring에서 권장하는 방법이다.

다른 방법들도 있지만 공식적으로 권장하지 않는다.

    public class Customer{
        ...
        private final discountPolicy discountPolicy;

        Customer(discountPolicy policy){
            this.discountPolicy = policy;
        }
    }

    public static void main(){
        ...
        Customer normal = new Customer(normalDiscountPolicy);
        Customer vip = new Customer(VipDiscountPolicy);
    }



생성자를 호출할 때 할인 정책을 설정할 수 있게 되므로

Customer가 생성될 때(로그인 시, 비로그인 주문 시 등등)

할인 정책을 결정할 수 있게 된다.

이게 바로 의존성을 외부에서 주입한다는 의미이다.

 

스프링과 DI

실제로 스프링에서는 아래와 같이

@Autowired 태그를 통해서

DB 작업을 위한 repository 설정이나, Service 설정 등

Bean 객체들을 의존성을 주입으로 사용하도록 권장하고 있다.

@Service
public class UserService {

    private UserRepository userRepository;
    private MemberService memberService;

    @Autowired
    public UserService(UserRepository userRepository, MemberService memberService) {
        this.userRepository = userRepository;
        this.memberService = memberService;
    }

}

 

때문에 변경이 필요한 부분은 적절하게 의존성 주입이 가능하도록

interface를 활용하여 설계하여야 한다.

 

출처

mangkyu님 블로그

인프런 스프링 MVC 강의 1편

인프런 스프링 핵심 원리 기본편

 

profile

주녁, DevNote

@junwork

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!