※ 본 게시글은 인프런 스프링 핵심 원리 - 기본편 강의를 바탕으로 작성하였습니다.
강의 내용을 참고하여 개인적으로 정리한 글입니다.
🐣 비즈니스 요구사항과 설계
- 회원 도메인 요구 사항
- 회원을 가입 및 조회 기능
- 회원은 BASIC, VIP 두 가지 등급 보유
- 회원 데이터는 자체 DB를 구축 가능, 외부 시스템과 연동 가능 (미확정)

- 주문과 할인 정책
- 회원은 상품 주문 가능
- 회원 등급에 따라 할인 정책 적용
- 할인 정책은 모든 VIP는 1,000원 할인해주는 고정 금액 할인 적용 (나중에 변경 가능)
- 할인 정책은 변경 가능성 높음
- 기본 할인 정책 미정, 할인을 적용하지 않을 수도 있음 (미확정)

- 주문 생성 - 클라이언트는 주문 서비스에 주문 생성을 요청
- 회원 조회 - 할인을 하기 위해서는 회원 등급 필요, 회원 저장소에서 회원을 조회
- 할인 적용 - 회원 등급에 따른 할인 여부를 할인 정책에 위임
- 주문 결과 반환 - 할인 결과를 포함한 주문 결과 반환
역할과 구현을 분리했기 때문에, 자유롭게 구현 객체를 조립
회원 저장소와 할인 정책을 유연하게 바꾸기 가능
🐣 회원 도메인 설계
회원 클래스 다이어그램

회원 객체 다이어그램

회원 도메인 분석
- 회원 등급
- enum(BASIC, VIP) - 회원 등급을 관리
- Member - 회원 엔티티를 관리하는 클래스
- MemberRepository - 회원 저장소 인터페이스
💡 HashMap은 스레드에 안전하지 않음
여러 스레드가 동시에 HashMap에 접근하면 문제가 발생
이를 해결하기 위해 실무에선 ConcurrentHashMap 사용
- MemoryMemberRepository - 메모리 회원 저장소 구현체
- MemberService - 회원 서비스 인터페이스
- MemberServiceImpl - MemberService를 구현하는 클래스
여기까지 의존 관계가 인터페이스 뿐만 아니라, 구현체까지 모두 의존
※ OCP, DIP 원칙을 모두 위반
🐣 주문과 할인 도메인 설계
주문과 할인 클래스 다이어그램

주문과 할인 객체 다이어그램


주문과 할인 도메인 분석
- DiscountPolicy - 할인 정책을 선언하는 인터페이스
- FixDiscountPolicy - 고정 할인 정책 구현체 / VIP면 1,000원 할인, 그 외 할인 없음
- Order - 주문 엔티티를 관리하는 클래스
- OrderService - 주문 서비스 인터페이스
- OrderServiceImpl - 주문 서비스 구현체
회원, 주문 엔티티에서 Long을 사용하는 이유
데이터가 생성되는 시점에서 해당 값이 할당
Id는 특정 시점에서 존재 할 수도 안할 수도 있음
long은 null이 못 들어감, Long은 들어갈 수 있기 때문
현 파트에선 스프링을 사용하지 않고 순수 자바 코드로만 구현
현재는 고정적인 할인 VIP 등급이면 1,000원 나머지는 할인 없다
만약 할인을 고정이 아닌 % 비율로 들어가면 어떻게 될까?