public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
다음과 같이 MemberSerive의 구현체를 구현했을 때
지금은 보면 private final MemberRepository memberRepository = new MemoryMemberRepository();
이런 식으로 MemberRepository 인터페이스에도 의존을 하고 있고, 구현체인 MemoryMemberRepository에도 의존을 하고 있다.
따라서 인터페이스에만 의존해야 한다는 DIP를 위배하고있다.
또한, memberRepository의 구현체를 변경할 시 MemberServiceImpl의 코드를 변경해서 새로 주입해야줘야 하므로 확장에는 열려있고 변경에는 닫혀있어야 한다는 OCP를 위배하게 된다.
public class OrderServiceImpl implements OrderService {
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}
문제점 발견
관심사를 분리하자
public class AppConfig {
public MemberService memberService(){
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl((new RateDiscountPolicy()), new MemoryMemberRepository());
}
}
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}

현재 AppConfig를 보면 중복이 있고, 역할에 따른 구현이 잘 안보임
기대하는 그림

리팩토링 전
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(
new MemoryMemberRepository(),
new FixDiscountPolicy());
}
}
리팩토링 후
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
private MemoryMemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService() {
return new OrderServiceImpl(discountPolicy(), memberRepository());
}
public DiscountPolicy discountPolicy() {
// return new RateDiscountPolicy();
return new FixDiscountPolicy();
}
}
AppConfig의 등장으로 애플리케이션이 크게 사용 영역과, 객체를 생성하고 구성(Configuration)하는 영역으로 분리되었다.


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