SPRING 관심사의 분리

손원진·2023년 4월 13일
0

[SPRING]

목록 보기
11/15

스프링을 하나의 공연이라고 생각해보자.

각각의 인터페이스를 배역이라고 생각하자. 배역에 맞는 배우를 선택하는 것은 누가해야할까? 로미오와 줄리엣이 있다고 하면 어떤 역할을 할지 배우들이 정하나?
아니다.

공연기획자가 진행하는 것이지, 배우가 하는 것이 아니다.

인터페이스(로미오)가 구현체(줄리엣) 역할을 하는 것을 직접 섭외하는 것과 다르지 않다. (DIP OCP 위반)

마치 배우가 직접 여자주인공을 초빙해서 진행하는 것과 마찬가지이다.

관심사를 분리를 해야한다. 배우는 배우의 역할 기획자는 기획자의 역할을 할 수 있도록 분리하는 것이다(인터페이스만 의존) 구현체에 의존하지 않음, 제어의 역전 DIP

APPCONFIG에 등장 - 애플리케이션의 전체 동작을 구성(CONFIG) 하기 위해 구현객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스

철저하게 dip를 지킨 orderServiceImpl 클래스

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discount;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy){
        this.memberRepository = memberRepository;
        this.discount = discountPolicy;
    }


    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findMember(memberId);
        int discountPrice = discount.discount(member,itemPrice);

        if(discountPrice==0){
            discountPrice =0;
        }
        Order order = new Order(memberId, itemName, itemPrice,discountPrice);

        return order;
    }
}

인터페이스(추상화)에만 의존하고 생성자를 통해서 구성을 주입해줌
new MemberRepositoryImpl and DiscountPolicy,

DIP 의존관계의 역전을 철저하게 지켰으며,
구성 APPCONFIG에서 구현체를 지정하면 되니 OCP도 지킨 것이됨

APPCONFIG CLASS 
 public MemberService memberService(){
        return new MemberServiceImpl(new MemberRepositoryImpl());
    }

    public OrderService orderService(){
        return new OrderServiceImpl(new MemberRepositoryImpl(), new FixDiscountPolicy());
    }
   
   

의존관계에 대한 고민은 외부에만 맡기고 실행에만 집중하면 된다.
객체를 생성하고 연결하는 역할과 실행하는 역할이 완벽하게 분리

클라이언트인 memberServiceImpl 입장에서 보면 의존관계를 마치 외부에서 주입하는 것 같다고해서 dependency injection(의존관계 주입)이라고 한다.

APPCONFIG는 역할들이 드러나도록 진행해야한다.

public class AppConfig {

   public MemberService memberService(){
       return new MemberServiceImpl(getMemberRepository());
   }

   private MemberRepositoryImpl getMemberRepository() {
       return new MemberRepositoryImpl();
   }

   public OrderService orderService(){
       return new OrderServiceImpl(getMemberRepository(), discountPolicy());
   }

   public DiscountPolicy discountPolicy(){
       return new FixDiscountPolicy();
   }
}

config에서 따로 메소드를 생성해 생성자에 주입하여, 어떠한 구현체를 주입하는지 확인할 수 있음

출처

https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8&unitId=55344&category=questionDetail

느낀점 -- 너무 재밌다. 책을 볼땐 몰랐는데 코드를 치면서 하니 더 이해가 잘된다.

이해가 안되는 부분이거나, 헷갈리는 부분만 따로 블로그에 정리해두자.

profile
매일 한 걸음

0개의 댓글