[Spring] 관심사의 분리, AppConfig

관심사의 분리

- 애플리케이션을 하나의 공연이라 생각해보자. 각각의 인터페이스를 배역(배우역할)이라 생각했을때, 실제 배역 맞는 배우를 선택하는 것은 누구인가? 

- 로미오와 줄리엣 공연을 하면 로미오 역할을 누가 할 지 줄리엣 역할을 누가 할지는 배우들이 정하는것이 아님

- 이전 코드는 마치 로미오 역할 (인터페이스)을 하는 레오나르도 딭카프리오(구현체,배우)가 줄리엣 역할(인터페이스)을 하는 여자주인공(구현체, 배우)을 직접 초빙하는 것과 같았음.

- 디카프리오는 공연도 해야하고 동시에 여자주인공도 공연에 직접 초빙해야하는 "다양한 책임"을 가지고 있었다.

>> 관심사를 분리하자

 

- 배우는 본인의 역할인 배역을 수행하는 것에만 집중해야한다.

- 디카프리오는 어떤 여자주인공이 선택되더라도 똑같이 공연을 할 수 있어야 한다.

- 공연을 구성하고, 담당배우를 섭외하고, 역할에 맞는 배우를 지정하는 책임을 담당하는 별도의 "공연기획자" 가 나올 시점.

- 공연기획자를 만들고, 배우와 공연 기획자의 책임을 확실히 분리하자 !

 

AppConfig 등장

- 애플리케이션의 전체 동작방식을 구성(config)하기 위해, "구현객체를 생성" 하고, "연결"하는 책임을 가지는 별도의 설정클래스를 만들자.

 

"AppConfig"

 

 

< 테스트코드에서 `@ErforeEach`는 각 테스트를 실행하기 전에 호출된다. >

 

정리

- AppConfig를 통해서 관심사를 확실하게 분리했다.

- 배역,배우를 생각

- AppConfig는 공연 기획자

- AppConfig는 구체 클래스를 선택한다. 배역에 맞는 담당배우를 선택, 애플리케이션이 어떻게 작동해야 할 지 전체 구성을 책임진다.

- 이제 각 배우들은 담당기능을 실행하는 책임만 지면 된다.

- 'orderServiceImpl'은 기능을 실행하는 책임만 지면 됨.

 

>> 리팩토링 시 

 

package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;

public class AppConfig {
    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository());
    }
    private MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(),discountPolicy());
    }
    public DiscountPolicy discountPolicy(){
        return new FixDiscountPolicy();
    }

}

- `new MemoryMemberRepository()` 이 부분이 중복제거되었다. 이제 `MemoryMemberRepository`를 다른 구현체로 변경할 때 부분만 변경하면 된다.

- `AppConfig`를 보면 역할과 구현클래스가 한눈에 들어온다. 애플리케이션 전체구성이 어떻게 되어있는지 빠르게 파악할 수 있다.