묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
context의 구별에 대하여
안녕하세요?코드 작성 중에 context가 상당히 많이 사용되고 있습니다. 그런데 어느 경우에는 this, 또 다른 경우에는 BaseContext, 또 다른 경우에는 context 등이 사용되고 있습니다.이것이 서로 어떻게 구별되는지요? 일정한 기준이 있는지, 있다면 어떤 방식으로 나뉠 수 있는 것인지 궁금합니다.
-
해결됨은행 서버 프로젝트 실습을 통해 배우는 코틀린 마스터 클래스
질문] 에러처리 관련 문의
현재 JWT 부분까지 들었습니다! 강의를 들으면서 갑자기 궁금한 부분이 생겨 질문드립니다.도메인 별로 현재 API (Controller) 도 나눠져있는데요, 이런 형태의 프로젝트(DDD 아키텍처)인 경우 @RestControllerAdvice를 활용한 글로벌예외처리는 어떻게 구성하시나요? 글로벌예외처리 전용 class를 만들고 특정 익셉션들을 구성 후 각각의 익센션에 대한 응답을 ResponseProvider 를 이용해서 하는지? 등...너무 추상적으로 질문을 드려서 이해하실지 모르겠지만 요약하자면 도메인별로 구별되어 있는 프로젝트에서는 글로벌익셉션처리가 어떤 형태로 구성할 수 있는지 궁금합니다 ㅋ.ㅋ;
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
DB 레이어 잘 다루는 법
안녕하세요. DB 레이어를 다루는 것에 대해 몇가지 질문이 있습니다.프로젝트 버전 1.1 포인트 적립 트랜잭션리뷰 작성ReviewService.addReview)에서 포인트 적립PointHandler.earn )이 한 트랜잭션에서 이루어져야 될 것 같다고 생각했는데 분리되어 있습니다. 이렇게 처리해도 충분한지 여쭤보고 싶습니다.CancelService, PaymentService 에서는 같은 트랜잭션에 있음 낙관적 락 예외 처리PointBalanceEntity 에는 동시성 처리를 위해 @Version(낙관적 락)을 두었다고 해주셨습니다.현재는 낙관적 락 예외가 발생하면 500 에러가 발생할 것으로 보이는데, 저는 평소 최대한 이 낙관적 락 예외를 잡아서 적절히 다른 예외로 변환하여 던지도록 했었습니다.낙관적 락 예외에 대해서 500에러가 발생하도록 처리하는 것으로 충분할지 고민됩니다. Repository, JpaRepository 분리 현재 프로젝트는 서비스 -> 컴포넌트(Finder, Handler, ...) -> JpaRepository 형태로 계층 관계가 있는 것 같습니다.그런데 재미니님의 유튜브를 보면 서비스 -> 컴포넌트(Finder, Handler, ...) -> Repository(개념 객체를 다루는?) -> JpaRepository 형태의 계층을 이루고 있는 것으로 보입니다.첫번째 계층구조를 보면 종종 서비스에서 단순히 컴포넌트를 한번 호출하는 정도인 경우가 많은 것 같습니다. 두번째 계층구조를 사용한다면 서비스에서 단순히 컴포넌트를 한번 호출하고, 그 컴포넌트에서도 단순히 Repository를 한번 호출하는 정도인 경우도 많이 생길 것 같습니다.이러한 이유로 저는 첫번째 계층구조 정도로 충분한가? 라고도 생각했는데 두번째 계층구조를 선택하시게 되는 이유가 궁금합니다. 두번째 계층구조 관련해서 여러 영상들이 있겠지만 우선 저는 아래 영상 참고했습니다.https://www.youtube.com/watch?v=b5xWS8MYl0Q Repository 가 분리된 경우에서의 검증, 업데이트 로직데이터를 검증, 업데이트할 때 어떤 재미니님과 같은 프로젝트 구조를 가져간다면 어떤 식으로 코드가 나오게 될 지 궁금합니다.검증, 업데이트라 하면 제가 생각한 예시 상황은 리뷰가 7주일이 지나면 업데이트 할 수 없다는 요건이 있다고 가정해보겠습니다.제가 생각한 것은 아래와 같습니다.public class ReviewService { private final ReviewFinder reviewFinder; private final ReviewProcessor reviewProcessor; public void update(ReviewUpdate reviewUpdate) { var review reviewFinder.get(reviewUpdate.id()); if (review.canUpdate()) { throw new CoreException(); } var updatedReview = review.update(reviewUpdate); reviewProcessor.update(updatedReview); } }이전에 프로젝트 구조에 대해서 고민이 많이 되었을 때 재미니님의 유튜브를 보면서 프로젝트 구조를 잡는데 도움이 많이 되었습니다.그런데 제가 그 의도나 스타일을 완전히 이해하지는 못하고 있는 것 같아서 재미니님의 스타일들을 한번 배워보고 싶습니다.유튜브에서부터 정말 도움 많이 받고있습니다. 좋은 강의 감사합니다!!
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
엔티티 연관관계 사용
안녕하세요, 강의 너무 잘보고있습니다!코드를 살펴보니 궁금한 부분이 있는데 현재 작성된 코드에서는 엔티티 간 연관관계를 맺지 않고 풀어내고계시더라고요!재미니님은 실무에서도 연관관계를 사용하지 않으시는 건지 아니면 고민 포인트(?)를 던져주신건지 궁금합니다!예를들어 Order와 OrderItem 관련해서, OrderService의 서비스 레이어인 create 메서드에서 OrderItemRepository를 사용해 saveAll을 호출하는 방식을 사용하시더라고요!저는 Order가 없으면 OrderItem은 존재하지 않아야한다고 생각해서, OrderItem의 생성을 서비스 레이어가 아닌 Order 엔티티안에서 생성하도록 강제하는 건 어떨까 생각했습니다.방법으로는OrderItem.create() 같은 생성 메서드를 protected로 막는다.OrderItemRepository를 아예 생성하지 않는다.더티 체킹을 이용하여 Order 필드에 있는 List<OrderItem> 컬렉션에 요소 추가로 OrderItem을 save한다.팀 컨벤션을 정한다.정도가 있을 것 같은데... 그렇다면 재미니님은 실무에서도 연관관계를 맺지 않는 방식을 선호하시는 건가요?사실 서비스 레이어에서 직접 호출을 통한 저장이라고 해도 문제는 없겠지만 사용하시는 방식이 궁금합니다! 그리고 추가적으로 주문 시 상품 재고를 차감시키는 메서드를 OrderHandler(OrderManager) 에 private으로 위치시키는 것과 ProductHandler(ProductManager)에 위치시키고 주입받아 사용하는 것중 어떤게 더 나은 방식일까요?private void decreaseProductStock(List<NewOrderItem> newOrderItems, Map<Long, Product> productMap) { for (NewOrderItem newOrderItem : newOrderItems) { Product product = productMap.get(newOrderItem.productId()); if (product.isStockLessThan(newOrderItem.quantity())) throw new ApiException(PRODUCT_QUANTITY_OVER); product.decreaseStock(newOrderItem.quantity()); } }고민이 되는 부분은 예를들어 위와 같은 메서드를 OrderHandler에 두자니 조금 헤비해지는 것 같고, ProductHandler에 두자니 신규 주문 시에만 사용될 것같은데.. ProductHandler에 두는게 맞는지 고민입니다..! 의견이나 힌트 주시면 좀 더 고민해보도록 하겠습니다!
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
엔티티 상태를 조회하는 시점
안녕하십니까 좋은 강의 잘듣고 있습니다.강의를 들으면서 예제 코드도 같이 파악해보고 있는데요repository 조회시 조회한 결과에서 활성 상태를 체크할때 2가지 방법으로 구현이 되어있는 것 같습니다.repository에서 쿼리 메서드로 값 전달 findByXXAndStatus()일단 findByXX로 조회하고 filter에서 isActive 체크 2가지 경우다 결과 자체는 Active인 엔티티를 조회하겠지만, 두 경우를 언제 사용하는 것이 좋은지가 구분이 있을까요?? 일단 저라면 목록을 조회하는 경우라면 1번 방법으로 조회하면 조금이나마 성능 이점이 있을 것 같고, 단일 데이터 조회시에는 1번이나 2번이나 상관은 없을꺼 같다는 생각입니다! https://youtu.be/o5byT9Ha5Tg?si=C1zj8oP8-wSB6g7Y최근에 우테코에서도 softDelete 관련 처리를 엔티티 설정을 통해 하기도 하던데, 제미니님의 의견이 궁금하여 질문드립니다! 감사합니다! ps. 아직 제가 강의를 쿠폰 부분까지 들어서 뒤에서 이에 대한 설명이 나오는지는 확인을 못했어요!
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
섹션3. 상품 상세. 코드느끼기 12:47 질문.
ProductFinder -> ProductUsecase or ProductUsecase<ProductSection>정의한 곳에 Product 서비스 와 ProductSection 서비스를 갖고 안에서 작업을 해보는건 어떻게 생각하실까요?ProductProductSecion 으로 명명하기에는 애매한 부분이 있어, Usecase라는 단어를 써서중간에 두 서비스만 사용하는 컴포넌트를 하나 두는 것은 어떻게 생각하실까요?혹은 Delegator 를 써서, 이 두 서비스를 의존해서 처리해야 하는 프로세스를 위임해버리는 타입을 하나 만드는겁니다.어떻게 생각하실까요?
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
xxx서비스와 xxx핸들러 의 구분 기준
안녕하세요!궁금한점이 생겼는데요.로직을 수행하는 객체중 어떤것은 xxx서비스 어떤것은 xxx핸들러또는매니저(컴포넌트) 등의 객체로 나눠지는데요. 이에 대한 기준이 있을까요?컨트롤러가 호출하는 객체를 xxx서비스, 서비스가 호출하는 객체를 xxx핸들러또는매니저(컴포넌트)라고 보면 될까요? 그렇다면 컴포넌트는 특정 개념에서의 로직들이 응집되어있는 객체 라고 보면 될까요?
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
상품 전체보기가 없습니다. 카테고리는 필수로 선택해야 합니다.
전체보기가 없는 상품들 목록이라면카테고리 프로덕트로 설계하는 방향은 어떻게 생각하시는지요?상품의 전체보기가 없습니다.A-Z까지 모든상품들은 카테고리로로 분류되어있고(=모든 상품들은 카테고리라는 꼬리표를 가집니다)좌측 메뉴탭에서도 카테고리별로 구분이 되어있습니다.해당 상품들을 모두 카테고리별로 선택의 상세보기에 해당상품들이 나열되도록 되어있습니다.이러한 생각은 어떤지 한번 의견 듣고싶어요.
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
@Transactional에 관해서 질문드립니다.
안녕하세요!강의를 보던 중 ReviewService의 트랜잭션 처리에 대해 궁금한 점이 있어 질문드립니다. addReview 함수에서 리뷰를 저장하는 add()와 포인트를 적립하는 earn() 두개의 중요한 함수를 사용하고 있는데, 이는 각각 별도의 트랜잭션으로 처리되어 리뷰는 저장되고 포인트는 적립되지 않는 문제가 발생할 수 있을 것 같습니다. 현재 설계에서 addReview()에 @Transactional을 붙이지 않은 특별한 이유가 있으신지 궁금합니다. 혹은 만약 의도적으로 별도 트랜잭션으로 분리한 것이라면 그 이유가 궁금합니다. 항상 감사합니다.
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
'개념과 격벽' 을 실제 업무에 어떻게 사용하면 좋을까요?
안녕하세요, 제미니님.유투브 및 인프런 강의 잘 시청하고 있습니다 :) 인프콘 2024에서 '지속 성장 가능한 설계를 만들어가는 방법' 이라는 주제로 발표해주신 내용이 무척 공감이 되었고, 제미니님 유투브를 찾아봤다가 강의까지 수강하게 되었습니다 이번 강의 내용은 아니지만 인프콘 영상에서 말씀해주신 개념인 '개념' 과 '격벽'을 구체적으로 실무에서 어떻게 사용하면 좋을지를 여쭤보고자 인프런 질문을 통해서 글을 올리게 되었습니다. 편의상 신규 프로젝트를 진행한다고 가정했을때,요구사항을 분석하고 도메인을 구성하는 여러 '개념'들을 나열한다.나열된 '개념'들의 급(1급, 2급, 3급 ..) 을 나눠보고 그룹화 하면서 '격벽'으로 분리한다.'격벽'으로 분리된 그룹이 어떤 개념을 통해서 연결될지 방화벽으로 동작할 개념을 생각해본다. 이는 개념간 무분별한 참조를 막기 위함이다.'개념'들과 '격벽'들을 기반으로 일단 코드로 구현부터 해본다. ('설계를 하지 말고 구현을 먼저' 하는 포인트는 이것)구현하면서 또는 운영하면서 더 나누거나 신규로 추가할 개념이 있다면 반영한다. 결과적으로 설계를 하지 않고 구현을 먼저 하고, 구현 하는 과정이나 운영 하는 과정에서 최적화 시킨다. 이것이 곧 최적의 설계로 나아가는 방향이 된다. (질문) 제가 제미니님이 말씀하신 '개념'과 '격벽'을 잘 이해한 것이 맞을까요? 실무에서 위 흐름대로 적용하면 제미니님이 강조하신 내용에 기반한 작업이 될 수 있을까요? 실무에서 실제로 말씀해주신 내용을 적용해보고 싶은데 구체적으로 어떤식으로 적용하면 될 지 몰라서 제가 이해한 내용을 바탕으로 작성을 해보았습니다. 틀린 부분이 있다면 피드백을 부탁드리고 싶습니다 :) 긴 글 읽어주셔서 감사합니다~
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
타임베이스 정산 배치 실패 시 처리에 대해
안녕하세요 시간날 때 틈틈히 보다가 어느새 막바지에 다다랐네요! 타임베이스 정산 배치가 실패했을 때 궁금한점이 있습니다. 우선 현재는 시간 대별로 오전 1시, 4시, 9시로 배치가 나눠져있는데이 상황에서 강의에서도 설명하셨듯이 오전 1시 배치가 오전 4시 30분에 끝나서 오전 4시의 배치가 에러가 뱉는 상황에 대해 문제를 해결하는 방법들이 궁금합니다! 우선 제가 생각한 방법들은 다음과 같습니다.1. 이벤트 기반 이벤트 기반으로 각 단계가 완료되면 바로 다름 배치 단계로 넘어가는 방식입니다.하지만 이 방법은 이미 기존 인프라와 코드를 변경해야하고 정산 시간이 고정 된다는 요구사항이 있다고도 보여 현재 요구사항에는 적절하진 않은 것 같습니다. 2. 각 배치마다 전 단계 완료 여부 상태를 확인오전 4시, 오전 9시 배치가 이전 단계의 배치 중 실패한 배치 이력이 있는지 확인하는 방법입니다.현재 스케줄링 방식으로는 이를 위해 별도의 배치 기록 테이블을 만들어서 배치 이력 관리를 추가합니다.오전 4시, 오전 9시에 해당 정산 날짜에 대해 실패한 이전 배치 단계 이력이 있다면 성공할 때 까지 N번 재시도 합니다.정산의 즉시성이 필요하다면 N번 재시도 후 실패했을 때 해당 배치 단계를 에러 상태로 처리하고,에러 로깅과 알림을 전송합니다.다음 배치 단계는 정산 날짜에 해당하는 이전 배치 이력이 에러 상태로 남아 있다면 실행하지 않습니다. 현재 요구사항에서는 수동으로 처리할 부분은 최대한 제거하는 2번 방식을 사용할 수 있을 것 같습니다.제가 배치 관리에 대해 잘 이해하고 있는지 모르겠어서 생각한 방법에 대해서 재민님은 어떻게 생각하시는지 궁금합니다.! 항상 잘 보고 있습니다 감사합니다!
-
해결됨[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
"프롤로그에서 ..." 오류 관련해 직전 질문에 대한 추가 질문입니다.
선생님, "프롤로그에서 ..." 오류 관련해 직전 질문에 대한 추가 질문입니다.지금의 상황에서 수평 관련 제약 조건이 추가되지 않는다면, 왜 문제의 오류가 발생하는 것인지요?지금의 경우 이처럼 constraintLayout을 써서 복잡하게 제약 조건이 필요하다면, 이때 차라리 그 전체 layout으로서 Linearlayout을 사용하는 것이 더 간단하지 않을까요?
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
강의 PDF는 어디에서 다운로드 할 수 있을까요?
"4. 강의 PDF 자료 및 프로젝트"에서 프로젝트 소스는 있는데 강의PDF는 안 보이네요..어디에서 강의 PDF를 찾을 수 있을까요?
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
취소-코드느끼기 / Cancel을 별도의 스키마로 관리하는 방식의 장점
안녕하세요, 강사님. 취소 - 코드느끼기 수업의 5:00~ 부분부터'결제', '취소'의 스키마를 분리하여 레코드를 immutable하게 다루는 상황의 예시로 결제 취소 상황을 설명하셨는데 어떤 부분에서 유리한건지 모르겠습니다. 7일 전 주문을 30일 후에 취소함'취소'를 '결제'의 상태로 반영할 때'결제'의 상태를 '취소'상태로 변경 - 레코드 수정 시각 갱신취소된 '결제' 조회 시 레코드 수정 시각을 이용해야 함'취소'를 스키마로 관리할 때새로운 '취소' 레코드 추가제가 이해한 상황은 '취소된 결제를 결제 id 없이 취소 시각으로 조회해야한다'는 것입니다.취소된 결제를 결제 id 대신 취소 시각으로 찾는 경우는 어떤 상황인지, 조회를 위해 어느정도 취소시각의 범위를 특정할 수 있는 데이터가 존재할텐데 데이터가 결제 id와 분리되어 존재하는 이유가 무엇인가요?'취소'스키마가 따로 존재해서 결제 취소가 레코드로 쌓일 때, 취소 시각으로 찾는다면 무엇이 다른건지 모르겠습니다.'규모적으로 선택하라. 테이블이 적고 테이블 로우가 적고 접근 범위 자체를 줄일 수 있고, 이런 장점으로 보면 페이먼트 테이블을 만들어도 되는데요' 라고 말씀하신 부분도 모르겠습니다!수업 진행하시면서 1) 각 개념의 레코드가 자신의 영역 안의 맥락으로만 수정된다, 2) '결제'의 레코드는 많고, '취소'의 레코드는 적으므로 취소 일자로 조회하는 속도 차이가 난다고 하시는 것은 이해했습니다만 앞서서 예시로 들어주신 부분은 잘 모르겠네요. 감사합니다.
-
해결됨은행 서버 프로젝트 실습을 통해 배우는 코틀린 마스터 클래스
강의_34] 공통 모듈 관련 질문입니다.
아직 MSA 경험이 없다보니 질문을 드려봅니다.메시지에 관련된 Entity를 공통 모듈로 뺀다고 하셨는데용Lecture_1 라는 프로젝트, Lecture_2 라는 프로젝트가 있다고 가정을 했을 때'공통 모듈' 이라는걸 별도의 프로젝트로 구성한다는 말씀이실까요?아니면 아래와 같이 프로젝트 root외에 모듈을 별도로 잡아서 한다는 말씀이실까영?rootProject.name = 'Lecture_2' include 'common' <-- 공통 모듈?rootProject.name = 'Lecture_2' include 'common' <-- 공통 모듈?아, 그리고 최근에는 MSA에 대한 단점이 명확해지고 있어서 Modular Monolithic 아키텍처도 생겨나고 있는데 강사님께서는 이 부분에 대해서 어떻게 생각하시는지도 궁금합니다!
-
해결됨[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
"프롤로그에서 콘텐츠가 허용되지 않습니다." 오류
선생님, 강의 잘 듣고 있습니다. 그런데 영탁 등등의 노래 리사이클러뷰 앱을 만들 때, 다음까지는 잘 됩니다.그런데 이후 <TextView> 부분에 background를 첨가하거나 텍스트를 바꾸기만 해도 계속 위의 제목에서 보인 오류가 뜨고, 이후 다른 fragment에서도 마찬가지 오류가 뜹니다.왜 그런 것이며, 어떻게 해결해야 할지요? 현재 최신 버전이 Otter를 사용하고 있습니다.<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Singer1Fragment"> <TextView android:text="영탁 노래 리스트" android:textColor="@color/black" android:gravity="center" android:layout_margin="10dp" android:textSize="30sp" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/singRV" android:layout_marginTop="50dp" android:layout_marginBottom="80dp" android:layout_width="match_parent" android:layout_height="match_parent"/> <!-- TODO: Update blank fragment layout --> <LinearLayout android:layout_width="match_parent" android:layout_height="80dp" app:layout_constraintBottom_toBottomOf="parent"> <ImageView android:id="@+id/image1" android:scaleType="fitXY" android:layout_weight="1" android:src="@drawable/photo1" android:layout_width="match_parent" android:layout_height="match_parent"/> <ImageView android:id="@+id/image2" android:scaleType="fitXY" android:layout_weight="1" android:src="@drawable/photo2" android:layout_width="match_parent" android:layout_height="match_parent"/> <ImageView android:id="@+id/image3" android:scaleType="fitXY" android:layout_weight="1" android:src="@drawable/photo3" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
companion object
안녕하세요 강사님 그 정적 팩토리 매서드는 강의에서 data class dto 측에 써 주셨는데 현업에서는 주로 dto에 쓰는 게 컨벤션인 가요?
-
해결됨누구보다 빠르게 배우는 Springboot + Flutter RestAPI 게시판 만들기
device선택시
디바이스 선택시 Chrome(web)과 저의 실물 핸드폰 연결해서 했더니 안드로이드 스튜디오 코드는 잘 돌아갑니다.하지만 BoardViewModel.dart 코드에서 설정한 url그대로 따라 쳤는데swagger ui에서계속 화면처럼 response body가 비어있습니다.. 계속나와서 혹시 전체 소스코드 공유 안될까요??
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
PointBalanceEntity에서 낙관적 락
안녕하세요! 강의를 듣다가 궁금한 것이 생겨서 질문 남깁니다.PointBalanceEntity에 낙관적 락을 추가해서 유저의 어뷰징을 방지한다고 하셨는데, 비관적 락이 아니라 낙관적 락을 사용하는 이유가 있을까요?포인트 적립이나 사용에 있어서는 충돌 가능성이 많지 않아서 낙관적 락만으로 해결 가능한 것인지, 아니면 비관적 락보다 성능이 더 좋아서 그런 것인지 궁금합니다.물론 말씀하신대로 상황마다 모두 다르겠지만, 대체로 어느 정도 규모가 있는 서비스에서도 낙관적 락만으로 해결이 되는 것인지도 궁금합니다.
-
해결됨제미니의 개발실무 - 커머스 백엔드 기본편
테스트 코드
안녕하세요 좋은 강의 잘 들었습니다~!강의를 모두 듣고 제공해주신 프로젝트를 쭉 확인하고 궁금한 점이 생겨서 문의를 남겨봅니다저는 실무에서 도메인 모델과 엔티티 모델을 구분하지 않고도메인 모델에 JPA관련 어노테이션을 모두 허용한 상태로 개발해왔습니다물론 구분해서 개발해본적도 있었지만컬럼 변경 등 다양한 변경사항에 대응할 때마다 도메인 모델과 엔티티모델을 둘 다 확인하고 변경해야하는 번거러움?이 생겼던거 같아서 클래스가 좀 지저분해지더라도 도메인 모델 하나로 개발하고 테스트 코드를 작성해왔었습니다이번 강의에서 사용된 프로젝트의 경우모듈과 패키지가 나눠져있어서 도메인 모델과 엔티티 모델이 분리되어있는듯 보이지만 제가 사용했던 구조와는 다른점이 있었습니다..!도메인 모델은 강의에서 말씀하신 개념과 격벽그리고 행동에 대해 적절하게 표현하기위한 객체이지만 핵심 비즈니스 로직을 모두 포함하고 있는게 아니라 대부분 조회된 데이터를 개념에 맞게 변경하는 DTO? 역할을 하는것 같고 상태변경에 대한 로직은 엔티티에 구현하고 service 레이어에서 호출하는 방식으로 보여집니다그렇지만 처음 보는 코드가 잘 읽힐정도로 충분히 설득력있는 구조라고 생각이 듭니다..다만 테스트 코드가 있어야만 그 설득력이 완벽해질것 같다는 생각이 들었습니다그래서 해당 프로젝트 구조를 더 이해하고 학습하기위해 테스트 코드를 작성해보려고 합니다만약 저라면 ~Entity에 작성되어있는 상태변경에 대한 테스트 코드와 ~Service, ~Handler, ~Manager 등에 작성된 로직에 대한 테스크 코드를 작성할 것 같은데강사님은 이러한 구조에서 테스트 코드를 어디까지 작성하시는지 또는 어떻게 접근하시는지 궁금합니다~!