1. 비지니스 요구사항과 설계

회원

  • 회원을 가입하고 조회할 수 있다.
  • 회원은 일반과 VIP 두 가지 등급이 있다.
  • 회원 데이터는 자체 DB를 구축할 수 있고, 외부 시스템과 연동할 수 있다. (미확정)

주문과 할인 정책

  • 회원은 상품을 주문할 수 있다.
  • 회원 등급에 따라 할인 정책을 적용할 수 있다.
  • 할인 정책은 모든 VIP는 1000원을 할인해주는 고정 금액 할인을 적용해달라. (나중에 변경 될 수 있다.)
  • 할인 정책은 변경 가능성이 높다. 회사의 기본 할인 정책을 아직 정하지 못했고, 오픈 직전까지 고민을 미루고 싶다. 최악의 경우 할인을 적용하지 않을 수도 있다. (미확정)

 


 

2. 개발 

  • 순수하게 자바 코드만 사용해서 개발
  • 역할(인터페이스)과 구현(구현체)을 분리해서 자유롭게 구현 객체를 조립할 수 있게 설계했다. 덕분에 회원 저장소는 물론이고, 할인 정책도 유연하게 변경할 수 있다.

 

새로운 할인 정책 개발

  • 유연한 설계가 가능하도록 객체지향 설계 원칙을 준수하며 개발했다.
  • 기존의 할인 정책인 FixDiscountPolicy 대신 새로운 할인 정책 RateDiscountPolicy로 변경하면 된다.
public class OrderServiceImpl implements OrderService {
	// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
	private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}

 

 

문제점 발견

  • 우리는 역할과 구현을 충실하게 분리했다. -> OK
  • 다형성도 활용하고, 인터페이스와 구현 객체를 분리했다. -> OK
  • OCP, DIP 같은 객체지향 설계 원칙을 충실히 준수했다 ->  NO
    • DIP 위반: 추상(인터페이스) 뿐만 아니라 구체(구현) 클래스에도 의존하고 있다.
    • OCP 위반: 지금 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 준다!

 

의존관계

기대했던 의존관계
실제 의존관계

클라이언트인 OrderServiceImpl 이 DiscountPolicy 인터페이스 뿐만 아니라 FixDiscountPolicy 인 구체 클래스도 함께 의존하고 있다. 실제 코드를 보면 의존하고 있다! DIP 위반

 

정책 변경

FixDiscountPolicy 를 RateDiscountPolicy 로 변경하는 순간 OrderServiceImpl 의 소스 코드도 함께 변경해야 한다! OCP 위반

 

문제 해결

DIP를 위반하지 않도록 인터페이스에만 의존하도록 의존관계를 변경하면 된다.

public class OrderServiceImpl implements OrderService {
	//private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
 	private DiscountPolicy discountPolicy;
}

인터페이스에만 의존하도록 설계와 코드를 변경했다.

❌ 또 다른 문제 발생! -> 구현체가 없어서 실행을 해보면 NPE(null pointer exception)가 발생한다.

 

해결방안

이 문제를 해결하려면 누군가가 구현 객체를 대신 생성하고 주입해주어야 한다.

그 누군가는 바로 스프링!!

 

 

 

다음 글 보러가기😋

2022.09.13 - [Spring] - 스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리2

 

스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리2

1. 관심사의 분리 AppConfig 등장 애플리케이션의 전체 동작 방식을 구성(config)하기 위해, 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스 AppConfig를 만든다. AppConfig는 애플리케

yiseul-coding.tistory.com

 

+ Recent posts