minsoo0715 / learn-spring-core-basic

김영한님의 스프링 핵심 원리 - 기본편 강좌를 수강하면서 작성하는 레포지토리입니다.
0 stars 0 forks source link

관심사의 분리 #2

Open minsoo0715 opened 11 months ago

minsoo0715 commented 11 months ago

커밋

OrderServiceImpl이 DIP를 만족하게 하기 위해서 DiscountPolicyMemberRepository의 할당을 없애고, 외부에서 Injection이 이루어지도록 생성자 작성 (생성자 주입) OrderServiceImplDiscountPolicyMemberRepository 인터페이스만을 바라봄

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy; // DIP 만족, 외부에서 주입이 필요

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

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

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}

AppConfig을 통해서 구현 클래스를 선택하는 역할을 수행하도록 함. 이제 각 구현 클래스는 어떤 구현 클래스가 주입될지를 알 필요가 없고 각자 기능에 대한 책임만 지면 됨. (어떤 면에서 LSP 관점에서 개선된 것으로 볼 수 있음.)

package hello.core;

import hello.core.discount.FixDiscountPolicy;
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(new MemoryMemberRepository()); // 생성자 주입
    }

    public OrderService orderService() {
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
    }
}
minsoo0715 commented 11 months ago

코드 (리팩토링)

커밋

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();
    }
}
minsoo0715 commented 11 months ago

효과

할인 정책을 변경했을 때 오직 AppConfig의 코드만 변경하면 됨. 사용 영역의 코드는 변경되지 않고, 구성 영역의 코드만 변경됨.

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