해당 강의는 김영한 강사님의 유료 강의로, 아주 간략하게 배운 부분들을 짚고 넘어가는 식으로 작성하였습니다.
생략된 부분이 많습니다. 전체 소스코드 공개도 금지이므로 블로그에 부분적으로만 올릴 생각입니다.
강의를 보며 포스트잇을 붙이는 느낌으로 제가 보기 위해 작성하는 글이니
학습을 위해서라면 아래 링크의 강의를 직접 들으시는 것을 추천합니다!
스프링 핵심 원리 - 기본편 - 인프런 | 강의
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...
www.inflearn.com
이전 글에서 회원 도메인 개발을 하다가 끊겼다. 이어서 작성하도록 하겠다.
회원 도메인 개발
회원 엔티티
~~
회원 저장소
~~
회원 서비스
~~
회원 도메인 실행과 테스트
회원 도메인 - 회원 가입 main
MemberApp으로 클래스를 생성한다. psvm을 입력하고 엔터치면 public static void main .. 이 자동으로 완성된다.id는 Long 타입이기때문에 1L과 같이 L을 붙여줘야 한다.
soutv 를 입력하고 엔터치면 System.out.println...이 자동으로 완성된다.
그런데 이렇게 애플리케이션 로직으로 메인메서드를 테스트를 하는 것은 한계가 있다.
JUnit이라는 테스트 프레임워크를 사용할 것이다.
test 의 hello.core에 member 패키지를 만들고 MemberServiceTest를 생성한다.
@Test를 작성한다. import org.junit.jupiter.api.Test; 해야한다.
join을 만들고 //given //when //then 을 작성한다.
given : 이런 이런게 주어졌을 때,
when : 이렇게 했을 때,
then : 이렇게 된다.
then에서 아래의 Assertions를 사용하면 된다.
Assertions.assertThat(member).isEqualTo(findMember);
다음과 같이 녹색불이 뜨면 성공이다.
현대적인 애플리케이션을 개발함에 있어 테스트 코드는 선택이 아니라 필수이다.
테스트 작성 방법을 필수로 알아야 한다.
이렇게 회원 도메인 설계를 해보았다.
그런데! 이 회원 도메인 설계에는 문제점이 있다고 한다.
> 과연 다른 저장소로 변경할 때 OCP 원칙을 잘 준수할까?
> 과연 DIP를 잘 지키고 있을까?
정답 : 의존관계가 인터페이스 뿐만 아니라 구현까지 모두 의존하는 문제점을 가지고 있다.
MemberServiceImpl를 살펴보자.
왼쪽을 보면 분명히 MemberRepository (인터페이스)를 의존한다.
그런데 문제는 오른쪽 MemoryMemberRepository이다.
실제 할당하는 부분이 구현체를 의존하고 있는 것이다!
그래서 지금 이 MemberServiceImpl은
MemberRepository(인터페이스)와 MemoryMemberRepository(구현체) 모두 의존하고 있는 것이다.
추상화에도 의존하고 구체화에도 의존하는 것이다. (쉽게 말하자면 DIP를 위반한다. 즉 안좋다는 뜻!)
주문과 할인 도메인 설계
주문과 할인 정책
~~
역할에 대해 그린 그림
~~
역할과 구현에 대한 그림
: 역할과 구현을 분리해서 자유롭게 구현 객체를 조립할 수 있게 설계했다.
회원 저장소는 물론이고, 할인 정책도 유연하게 변경할 수 있다.
주문 도메인 클래스 다이어그램
~~
역할, 구현 분리했으므로 역할들의 협력 관계를 그대로 재사용 할 수 있다.
주문과 할인 도메인 개발
할인 정책 인터페이스
할인 정책 인터페이스를 만들어야 한다.
discount 패키지와 DiscountPolicy 인터페이스를 생성한다.
정액 할인 정책 구현체
그리고 구현체인 FixDiscountPolicy 를 생성한다.
member.getGrade() == Grade.VIP 일 경우 discountFixAmount (1000원 고정)을 리턴한다.
참고로 enum 타입은 '==' 을 쓰는게 맞다.
주문 엔티티
이와 같이 order 패키지를 만들고 주문 엔티티를 생성한다.
memberId, itemName, itemPrice, discountPrice
당연히 생성자, getter, setter도 작성한다.
할인된 가격을 알아야하니 여기에다 간단한 계산 로직도 작성한다.
itemPrice에서 discountPrice를 빼면 된다.
( TIP : 보기 쉽게 출력하려면 우클릭 - Generate - toString() 이용하면 된다.
이 객체를 출력하면 toString() 결과가 쭉 나온다.
예를 들어 System.out.println("~~" + order); 와 같이 객체 자체를 출력할 경우,
이 toString()이 호출된다. )
주문 서비스 인터페이스
memberId, itemName, itemPrice를 파라미터로 넘기고 주문결과를 반환하여야 한다.
Order createOrder(Long memberId, String itemName, int itemPrice);
주문 서비스 구현체
주문 생성 요청이 오면 회원 정보를 조회하고, 할인 정책을 적용해 다음 주문 객체를 생성해 반환한다.
discountPolicy에 member 통채로와 itemPrice를 넘겨 discountPrice에 받았다.
그리고 return new Order(memberId, itemName, itemPrice, discountPrice);
주문과 할인 정책 테스트
JUnit 테스트를 사용해보자.
...
...
Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000)
실행 결과
여기까지 순수하게 자바 코드만으로 코드를 작성해보았다.
역할과 구현을 잘 나누어 소스코드를 작성했다.
하지만 과연 지금의 정액할인정책에서 정률할인정책으로 깔끔하게 바꿀 수 있는가?
다음 시간에 이에 대해서 학습할 예정이다.
스프링 핵심 원리 이해 - 예제 만들기 글은 여기서 끝내도록 하겠다.
'김영한님의 스프링 강의 학습 > 스프링 핵심 원리' 카테고리의 다른 글
#3 스프링 핵심 원리 이해2 - 객체지향 원리 적용2 (0) | 2022.10.01 |
---|---|
#3 스프링 핵심 원리 이해2 - 객체지향 원리 적용1 (1) | 2022.09.30 |
#2 스프링 핵심 원리 이해 - 예제 만들기1 (0) | 2022.09.28 |
#1 객체 지향 설계와 스프링 (0) | 2022.07.07 |
#0 스프링 핵심 원리 - 기본편 목차 (0) | 2022.07.06 |