Backend/Spring

[섹션 3]스프링 핵심 원리 이해2 - 객체 지향 원리 적용

지미닝 2024. 3. 18. 20:43

본 게시물은 김영한 선생님의 강의를 학습하며 작성하였습니다.

새로운 할인 정책 개발

→ 새로운 할인 정책을 확장시킬 수 있도록.

**RateDiscountPolicy**

“아 고정 1000원 할인하는거보다는 그냥 퍼센트로 할인하는게 낫지 않을까요~”

“계획을 따르기 보다 변화에 대응하기를..”

해결방법: DiscountPolicy interface에 FixDiscountPolicyRateDiscountPolicy를 종속시키면 된다!!

  • RateDiscountPolicy
package com.hello.core.discount;

import com.hello.core.member.Grade;
import com.hello.core.member.Member;

public class RateDiscountPolicy implements DiscountPolicy {
    private int discountPercent = 10;

    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP) {
            return price * discountPercent / 100; // 굉..장히 의심스로운 logic
        } else {
            return 0;
        }
    }
}

새로운 할인 정책 적용

단순히 OrderServiceImpl를 아래와 같이 고쳤다고 해서 해결될 문제가 아님!

private final MemberRepository memberRepository = new MemoryMemberRepository();
//  private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy(); // RateDiscountPolicy로 변경..
  • 추상인터페이스 뿐만 아니라 구체 인터페이스에서도 의존하고 있는 상태 (DIP위반)
    • 추상 클래스(인터페이스) 의존: DiscountPolicy
    • 구체 클래스: FixDiscountPolicy, RateDiscountPlolicy

기대했던 의존 관계

실제 의존 관계

DIP를 위반하고 있기 때문에, fixdiscountpolicy에서 ratediscountpolicy로 바꾸는 순간 orderserviceimpl코드도 바꿔야하는 사고가 생김

어떻게 해결할 수 있을까?

인퍼페이스에만 의존하도록 의존관계를 변경하면 된닷!

package com.hello.core.order;

import com.hello.core.discount.DiscountPolicy;
import com.hello.core.discount.FixDiscountPolicy;
import com.hello.core.discount.RateDiscountPolicy;
import com.hello.core.member.Member;
import com.hello.core.member.MemberRepository;
import com.hello.core.member.MemoryMemberRepository;

public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository = new MemoryMemberRepository();
    private 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);
    }
}

→ 인터페이스만으로는 안돌아간다…

누군가 클라이언트인 orderserviceInpl에 DiscountPolicy를 대신 생성하고 대신 주입해주어야 한다!