들어가기 앞서
•
강의 유튜브 링크
제가 강의 영상을 편집하면서 느꼈는데 엑스칼리드로우 설명 부분에서 Root에 대해 조금 모호하게 설명한 것 같아요. 보충 설명을 드리자면,
1.
다른 Aggregate끼리의 참조는 객체 그 자체가 아니라 ID로 참조해야 하며
2.
그 ID는 반드시 Aggregate Root의 ID여야 한다.
이렇게 알아두시면 돼요!
•
강의 자료
•
Github 링크
이번 주차 진행 전 확인해주세요!
이번 주차 실습에 필요한 코드는 week2 브랜치 내에 작성되어 있어요. 위에 첨부한 깃허브 링크를 참고해주세요! 실습 코드 안에 있는 TODO 주석을 중점으로 봐 주시면 좋아요. 제가 작성한 과제 정답 코드는 다음 강의가 올라가기 전날 오후에 week2-done 브랜치로 업로드 해드릴 예정이에요.
안녕하세요, 실전 백엔드 스터디 멘토 유도훈입니다. 

우선, 사과의 말씀 드리겠습니다. 이번 강의 영상 길이가 1시간 15분입니다…
코드에 대한 부연 설명을 너무 많이 했나봅니다..
1.5배속 하고 들으셔도 좋을 것 같아요.
1.5배속 하고 들으셔도 좋을 것 같아요.
이번 주는 이런 걸 배웠어요.
2주차에는 DDD에서 사용하는 다양한 용어들을 알아봤는데요, Entity와 Value Object, Aggregate, 그리고 불변식까지 이름이 꽤 많이 나왔죠? 조금 어려우셨을 수도 있을 것 같아요. 그래서 이번 주 과제는 WIL을 집중적으로 작성해주시면 좋을 것 같습니다.
1주차의 Product는 혼자서 자기 규칙을 지킬 수 있었지만, 이번 주차에서의 Order는 조금 달랐어요. 총액은 항목 금액의 합이어야 한다는 규칙은 주문(Order) 혼자서도, 항목(OrderItem) 혼자서도 판단할 수 없었죠. 이렇게 여러 객체에 걸쳐 있는 규칙(불변식)이 있으면 그 객체를 한 덩어리로 묶는데, 그 묶음을 Aggregate라고 했었죠?
Order 객체에 OrderItem을 넣으려면 Order 클래스 안에 있는 addItem()을 거쳐야 하고, Order 객체를 생성하기 위해서는 Order 클래스 안에 있는 place()를 거쳐야 했어요. 저희가 무언가를 하고 싶을 때, 그걸 도와주는 메서드는 단 하나뿐이에요. 동작마다 통로가 하나씩만 열려 있는 거예요. 그리고 그 통로들은 전부 Order라는 Root 안에 있어요. 바깥에서 Order Aggregate안에 있는 어떤 엔티티의 값이나 상태를 바꾸려면 반드시 Order를 거쳐야 한다는 뜻이죠.
질문! OrderItem에도 메서드가 있는데요?
A: OrderItem의 subtotal()처럼, Aggregate Root가 아닌 엔티티에도 메서드는 있습니다. 하지만 바깥에서 부를 수 있는 메서드들은 오직 읽기만 합니다. subtotal()은 price와 quantity를 곱해서 Money 객체로 돌려주는 역할을 합니다. 이 로직에서 어떠한 엔티티의 값이나 상태도 바꾸지 않습니다.
assignTo() 메서드 같은 경우에는 OrderItem의 값을 스스로 바꾸긴 하지만, 이는 바깥에서는 부를 수 없고, Order의 addItem() 안에서만 쓰이고 있기에 무방합니다.
핵심은
•
한 애그리거트에 속한 객체를 다른 애그리거트가 저장하고 싶을 때는 애그리거트 루트의 ID만 저장한다.
•
그리고 그 객체의 값을 조회해야 할 때 저장했던 ID를 가지고 레포지토리 계층에게 애그리거트 루트를 찾아달라고 부탁한다. 그 후, 반환된 애그리거트 루트에게 ID를 주고 값을 알려달라고 부탁한다.
•
이렇게 해서 받은 정보를 읽기만 하는 것(즉, read 하고 싶다면)은 가능하다.
•
하지만 이 정보의 값을 고치고 싶다면(즉, write 하고 싶다면) 다시 루트의 메서드를 통해 값을 고쳐달라고 부탁한다. 값을 직접 고치는 것은 올바른 구조가 아니다.
다음 3주차에서는 코드의 위치를 중점적으로 다루어 볼 예정이에요. 실제 DDD 아키텍처에서 사용하는 4계층을 알아보고 어떻게 코드를 옮겼는지 확인해 볼 거예요. 그리고 서비스 코드가 이제는 JPA라는 외부 기술도 알지 못하게 바꾸어 볼 계획입니다.
강의나 과제에 질문이 있다면 디스코드 #정규스터디-질문방 채널 혹은 개인 디스코드 메시지(닉네임: 도훈)로 연락 주세요!
과제
목표
•
WIL 작성
•
부분 취소 구현하기 (코드 제출!!)
WIL 작성
2주차 강의 및 실습 내용을 week2/wil.md에 정리해주세요.
꼭 300자 이상 작성해주셔야 해요!!
아래는 wil을 작성하시면서 한 번쯤 생각해보시길 추천드리는 내용이에요. 모두 작성하진 않으셔도 돼요!
•
어떤 프로젝트에서 주로 DDD를 도입할까? GDG의 프로젝트 트랙에서도 DDD를 사용할 수 있는 걸까? (이 내용은 꼭 한 번 생각해 보셨으면 좋겠어요!!)
◦
DDD는 좋은 걸까? 장점과 단점은 무엇일까?
•
금융, 핀테크 등 “돈”이 중요한 커머스 기업에서는 BigDecimal을 애용한다. 왜?
•
이펙티브 자바: 생성자 대신 정적 팩토리 메서드를 고려하라.
•
GoF 패턴 (양이 너무 많으니 관심있으신 분들만!!)
부분 취소 구현해보기 & 코드를 더 견고하게
1. Product에 있는 Quantity Value Object 적용시키기
1주차에는 Quantity VO가 없어서 int로 지정했지만, 이제는 VO가 생겼죠? 한번 바꿔봅시다. 바꾼 뒤에 Test 코드를 실행시켜서 전부 성공하는지도 확인해 보셔야겠죠?!
2. 부분 취소 구현하기
주문 항목 하나만 취소하는 cancelItem을 만들어보세요. (테스트 코드도 작성하면 더욱 좋습니다. 어떤 테스트가 필요할까요?)
•
불변식: 주문에는 항목이 1개 이상이어야 한다.
이 불변식을 어떻게 지킬 수 있을까요? 어떻게 조치하였는지 코드 내부 주석으로 작성해주세요.
참고사항
TODO 코드 위치
TODO 위치
이번 주의 TODO는 강의 영상에서 전부 채웠어요, 각 TODO에서 무엇을 했는지 다시 한 번 돌아봐요!
단계 | 구현 위치 | 할 일 |
W2-1 | Money | 생성자에서 음수 금액 거부하기 |
W2-2 | Money | add와 multiply 메서드에서 새 Money를 반환하도록 구현하기 |
W2-3 | Quantity | 생성자에서 1개 미만 거부하기 |
W2-4 | Order | addItem 메서드에서 CREATED 상태에서만 항목을 추가하도록 구현하기 |
W2-5 | Order | cancel 메서드에서 배송 시작 후에는 취소할 수 없도록 구현하기 |
W2-6 | Order | totalAmount 메서드에서 항목 금액의 합을 반환하도록 구현하기 |
W2-7 | Order | place 생성자에서 불변식을 지킬 수 있도록 구현하기 |
W2-8 | Order | getOrderItems 메서드에서 바깥에서 목록을 수정할 수 없도록 구현하기 |
제출해야 할 파일과 파일 경로
•
작성한 코드
•
wil.md - 배운 점 300자 이상!
[여러분들의 저장소 이름]
├── readme.md
├── .gitignore
├── commerce // 실습 코드, 필수
└── week1/
├── wil.md
└── hw1.md
└── week2/
└── wil.md // 필수
Plain Text
복사
부록
week2 브랜치가 안 보여요!
다음 공지를 참고해주세요!
마감 기한
와우스터디에서 확인해주세요.
제출 방법
자신의 레포지토리에 weekn 폴더를 생성해 wil.md 파일을 제출합니다.
더 자세한 사항은 아래 링크를 참조해주세요.






