카테고리 없음

[스프링 핵심 원리 - 기본편] 객체 지향 원리 적용

kangchaewon 2024. 1. 18. 22:22

객체지향 원리 DIP, OCP

public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository = new MemoryMemberRepository();
//    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// FixDiscountPolicy -> RateDiscountPolicy로 바꾸기 위해 코드 변경
    private final DiscountPolicy discountPolicy = new RateDiscountPolicy(); 
    @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);
    }
}

문제점 : 인터페이스에 의존해야하는데, 인터페이스와 구체클래스 모두 의존 -> DIP위반

문제점 : 변경하지 않고 확장 할 수 있어야 하는데, 지금 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 준다 -> OCP위반

해결방안 : 누군가가 클라이언트인 ServiceImpl에 DiscountPolicy의 구현 객체를 대신 생성하고 주입해야 한다.

 

public class OrderServiceImpl implements OrderService {
    private MemberRepository memberRepository;
    private  DiscountPolicy discountPolicy;

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

    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }
    public OrderService orderService() {
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
    }
}

-> 외부에서 생성자를 통해 주입

AppConfig리펙토링

public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @NotNull
    private MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    public DiscountPolicy discountPolicy() {
        return new FixDiscountPolicy();
    }
}

 

새로운 구조와 할인 정책 적용

AppConfig의 등장으로 사용 영역과 객체를 생성하고 구성하는 영역으로 나뉘었다.

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

ServiceImpl 바꿀 필요 x -> AppConfig만 수정하면 된다.

좋은 객체 지향 설계의 5가지 원칙의 적용

IoC, DI, 그리고 컨테이너

정적인 클래스 의존관계

IoC 컨테이너, DI컨테이너

- AppConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해 주는 것을 IoC컨테이너 또는 DI컨테이너라고 한다.

 

 

 

ctrl + b : 이동

crtl + alt + v : 클래스 객체 생성