4. 관심사 분리
관심사의 분리
각각의 인터페이스를 배역(배우 역할)이라고 생각해보자.
이때 역할에 맞는 배우들은 누가 선택할까?
누가 로미오 역할을 할지는 배우들이 선택하는것이 아니다.
이전 코드는 마치 로미오 역할을 하는 디카프리오가 줄리엣 역할을 하는 여자주인공을 직접 선택한 것과 같다.
디카프리오는 공연도 해야하고 여자주인공도 선택해야하는 다양한 책임을 갖게 되는것이다.
코드로 설명해본다면 인터페이스의 구현체인 MemberServiceImpl가 저장소 인터페이스의 구현체를 직접 선택한다는 것이다.
이때 필요한 것이 " 관심사를 분리" 하는 것이다.
배우는 본인의 역할인 배역을 수행하는 것에만 집중해야한다.
디카프리오는 어떤 여자 주인공이 선택되더라도 똑같이 공연할 수 있어야한다.
이를 위해서 배역에 맞는 배우들을 지정하는 책임을 갖는 " 공연 기획자 " 가 필요하다.
AppConfig
- 공연기획자
위에서 설명한 공연 기획자의 역할을 하는 것이 AppConfig 클래스이다.
- 애플리케이션의 전반적인 운영에 대한 부분을 관리
- 구현 객체를 생성하고, 연결하는 책임을 갖고있음.
원래는 필요한 클래스가 있다면 해당 객체를 직접 만들어줬지만 지금부터는 이러한 객체를 외부에서 생성하고 이 값을 주입 받을 건데 주입 받는 방법으로 생성자 주입을 이용해보자.
생성자 주입이란 해당 클래스의 생성자에 필요한 객체를 매개변수로 하여 주입 받는 방법이다.
이제 각각의 클래스의 코드들을 수정해보자
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
memberRepository의 값으로 어떤 구현체가 들어올지는 더이상 클라이언트인 MemberServiceImpl는 알지 못한다
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
이렇게 두 클래스의 코드를 수정하면 각각의 클래스는 자신의 구현체가 무엇이되는지 알고 있지 못한다.
즉, 인터페이스에만 의존하고 있기 때문에 DIP를 지킬 수 있게 된다.
이제 매개변수로 설정되어있는 각각의 객체들의 값을 설정해줄 클래스가 필요하다.
바로 이 설정을 AppConfig 클래스를 통해 해보도록 하자.
public class AppConfig{
public MemberService memberService(){
return new memberServiceImpl(new MemoryMemberRepository() );
public OrderService orderService(){
return new orderServiceImpl(new MemorymemberRepository(),new FixDiscountPolicy() );
}
앞으로는 우리가 직접 객체를 생성하는 것이 아닌 AppConfig 클래스를 통해 객체를 생성하게 된다.
- 사용 클래스 - MemberApp
//MemberService memberService= new MemberServiceImpl();
AppConfig appConfig= new AppConfig();
MemberService memberService = appConfig.memberService();
2. 사용 클래스 - OrderApp
//MemberService memberService = new MemberServiceImpl();
//OrderService orderService= new OrderServiceImpl();
AppConfig appConfig= new AppConfig();
MemberService memberService = appConfig.memberService();
OrderService orderService = appConfig.orderService();
AppConfig 의 특징
AppConfig는 인터페이스의 구현체를 만드는 동시에 의존관계를 같이 설정해준다!!
의존관계 주입 = 의존성 주입
생성자를 통해 인터페이스의 구현체가 만들어지는 동시에 의존관계가 있는 클래스의 객체가 생성되어 주입된다.
이때 주입해주는 것은 사용자(우리)가 아닌 AppConfig클래스이다.