-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[멀티 모듈 연동] 킬리안(박명규) 제출합니다 🚀 #104
base: audrb96
Are you sure you want to change the base?
[멀티 모듈 연동] 킬리안(박명규) 제출합니다 🚀 #104
Conversation
- "/" 요청 시 "/admin/index.html" 페이지 응답
- "/admin/reservation" 요청 시 "/admin/reservation-legacy.html" 페이지 응답
- reservation query controller 생성 - reservation service 생성 - response dto 생성 - reservation 도메인 객체 생성
- 패키지 구조 변경 - InMemory Reservation Repository 구현 - 예약 생성 API 개발
- id가 존재하는지 확인 후 save 방식 결정
- generatedKeyHolder.getKey()가 insert가 아닌 update가 수행되는경우 null을 리턴하게 되는 문제 수정
…agement/step1-2 # Conflicts: # src/main/java/roomescape/repository/ReservationRepository.java
…agement/step2-2 # Conflicts: # src/main/java/roomescape/application/api/ReservationCommandApi.java # src/main/java/roomescape/application/api/ReservationQueryApi.java # src/main/java/roomescape/application/service/ReservationService.java # src/main/java/roomescape/repository/ReservationRepository.java # src/main/java/roomescape/repository/memory/InMemoryReservationRepository.java # src/main/java/roomescape/repository/mysql/MySQLJdbcReservationRepository.java # src/main/resources/db/data/init.sql # src/main/resources/db/schema/schema.sql # src/test/java/roomescape/repository/mysql/MySQLJdbcReservationRepositoryTest.java
…agement/step2-2 # Conflicts: # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/ReservationTimeCommandApi.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/ReservationTimeQueryApi.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/ThemeCommandApi.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/ThemeQueryApi.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/request/CreateReservationTimeRequest.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/request/CreateThemeRequest.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/CreateReservationResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/CreateReservationTimeResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/CreateThemeResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/FindAllReservationTimesResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/FindAllReservationsResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/presentation/api/dto/response/FindAllThemesResponse.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/ReservationCommandService.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/ReservationQueryService.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/ReservationTimeService.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/ThemeService.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/command/CreateReservationTimeCommand.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/command/CreateThemeCommand.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/command/DeleteReservationTimeCommand.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/command/DeleteThemeCommand.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/creator/ReservationCreator.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/reader/ReservationTimeReader.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/reader/ThemeReader.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/validator/CreateReservationTimeValidator.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/validator/CreateReservationValidator.java # application/api/roomescape-reservation-api/src/main/java/roomescape/application/service/component/validator/DeleteReservationTimeValidator.java # application/api/roomescape-reservation-api/src/main/resources/static/js/reservation-new.js # application/api/roomescape-reservation-api/src/main/resources/static/js/theme.js # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/ReservationCommandApiTest.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/ReservationTimeCommandApiTest.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/ReservationTimeQueryApiTest.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/ThemeCommandApiTest.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/ThemeQueryApiTest.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/api/config/MockMvcCharacterEncodingConfig.java # application/api/roomescape-reservation-api/src/test/java/roomescape/presentation/controller/AdminPageControllerTest.java # build.gradle # core/core-db/roomescape-mysql-jdbc-db/src/test/java/roomescape/repository/mysql/MySQLJdbcReservationRepositoryTest.java # core/core-db/roomescape-mysql-jdbc-db/src/test/java/roomescape/repository/mysql/MySQLJdbcReservationTimeRepositoryTest.java # core/core-db/roomescape-mysql-jdbc-db/src/test/java/roomescape/repository/mysql/MySQLJdbcThemeRepositoryTest.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/ReservationView.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/ReservationViews.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/service/ClockHolder.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/service/CreateReservationValidator.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/service/SystemClockHolder.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/vo/ReservationDate.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/domain/reservation/vo/ReservationId.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/util/ObjectUtils.java # core/core-domain/roomescape-reservation-domain/src/main/java/roomescape/util/validator/ObjectValidator.java # src/main/java/roomescape/application/api/ReservationCommandApi.java # src/main/java/roomescape/application/api/ReservationQueryApi.java # src/main/java/roomescape/application/api/dto/request/CreateReservationRequest.java # src/main/java/roomescape/application/mapper/ReservationEntityMapper.java # src/main/java/roomescape/application/mapper/ReservationMapper.java # src/main/java/roomescape/application/service/command/CreateReservationCommand.java # src/main/java/roomescape/domain/reservation/Reservation.java # src/main/java/roomescape/domain/reservation/vo/ReservationDateTime.java # src/main/java/roomescape/repository/ReservationRepository.java # src/main/java/roomescape/repository/entity/ReservationEntity.java # src/main/java/roomescape/repository/memory/InMemoryReservationRepository.java # src/main/java/roomescape/repository/mysql/MySQLJdbcReservationRepository.java # src/main/resources/db/data/init.sql # src/main/resources/db/schema/schema.sql # src/main/resources/static/js/time.js # src/main/resources/templates/admin/index.html # src/main/resources/templates/admin/reservation-legacy.html # src/main/resources/templates/admin/reservation.html # src/main/resources/templates/admin/time.html # src/test/java/roomescape/MissionStepTest.java # src/test/java/roomescape/application/api/ReservationQueryApiTest.java # src/test/java/roomescape/application/controller/AdminPageControllerTest.java # src/test/java/roomescape/controller/AdminPageControllerTest.java # src/test/java/roomescape/domain/reservation/vo/ReservationDateTimeTest.java # src/test/java/roomescape/repository/momory/InMemoryReservationRepositoryTest.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 명규님!
제가 멀티모듈에 대한 경험이 없다보니 이 부분에서 큰 도움이 될 진 모르겠지만
코드 보시고 왜 이렇게 했는지 궁금한 부분이 있으면 말씀해주세요!
브라운과 의견을 나누고 싶습니다.
이 코멘트를 기반해서 궁금한 부분을 몇가지 적어보겠습니다.
- 모듈을 나누는 기준은 어떻게 설정해두셨는지?
- 우선 멀티모듈로 설계를 하는 상황이 어떤 상황을 염두해두신건지 궁금합니다.
- 사실 이정도 규모의 프로젝트에서는 모듈로 나누는게 오히려 구조적으로 유지보수를 힘들게 만드는 요인이 될 수 있습니다.
- 어떤 이점을 고려해서 설계를 하셨고, 그럼 그 이점을 얻기 위해 어떤 기준으로 모듈을 구분하셨는지 궁금합니다.
- 도메인 모듈에는 도메인 로직이 하나도 없는데 의도하신건지 궁금합니다.
- 도메인과 관련된 로직(생성을 포함한 기타 밸리데이션 등)이 도메인 모듈이 아닌 애플리케이션 모듈에 존재하는데 혹시 어떤 이유인지 궁금합니다.
- 그리고 로직이 없다면 도메인의 존재의 의도가 궁금합니다.
@boorownie 일단 제가 코드를 작성할 때,
모듈을 나누는 기준은 아래와 같습니다.
일단 회사 코드를 경험하면서 계층간의 구분없이 레이어간 의존성이 양방향으로 되어있거나 순환되게 설계되어 코드에 수정사항이 있을 때
위와 같은 상황에서 어느 한 레이어의 코드 수정이 있다고 한다면 그 영향은 양방향으로 퍼져갈 것입니다. 그리고 모듈간의 독립적이라는 장점을 통해 의존성 관리를 작게 유지할 수 있습니다. 하지만 모듈 별로 필요한 의존성만 작게 나누어서 관리한다면 그 범위는 의존성을 가지고 있는 모듈만으로 한정지어지게 될 것입니다.
맞습니다. 작은 규모의 프로젝트에서는 유지 보수를 힘들게 만드는 요인이 될 수 있습니다. 이게 실제 회사 프로젝트라도 초반에는 작은 프로젝트니까 아키텍처 고려하지 말고 그냥 단순하게 만들자. 라고 시작하고 개발 완료했다가.
의도했다기 보다는 아직 복잡한 도메인 로직이 없었습니다. 일단 도메인에서 말하는 엔티티와 DB 에서 말하는 엔티티(JPA 엔티티는 이쪽에 가깝다고 생각합니다) 는 다르다고 생각합니다. 도메인 엔티티는 비즈니스 로직의 핵심을 담고 있는 엔티티로 실제 로직에서 객체간의 상호작용을 통해 우리가 해결하고자 하는 문제를 해결하는 행동 중심의 엔티티입니다. 두 엔티티를 같이 썼을 때 나올 수 있는 문제는 다음과 같습니다.
거대한 서비스에서 DB 변경은 아예 고려안해도 되지 않나요?? DB 변경은 아예 불가능한 서비스일 수 있는데?
많은 서비스가 모놀리식에서 MSA로 바뀌어 가고있는 상황에서 DB 변경과 같은 일은 충분히 일어날 수 있다고 생각이 듭니다. 그럼 여기서 DB Enitity의 역할은 무엇일까요? 비즈니스 로직이 작을때는 DB에 접근하는 엔티티와 도메인에 접근하는 엔티티를 같은 것으로 사용하면 되지 않나요? 일 수 있습니다. 현재 도메인에 엄청나게 많은 로직이 있지는 않지만 이렇게 나누어 놓음으로써 핵심 비즈니스 로직이 추가 되었을 때 그 의미가 있다고 생각이 듭니다. 여기까지가 제 생각이였습니다! 너무 든든하게 국밥같은 느낌으로 작성했습니다...! 😅 |
안녕하세요 명규님! 든든한 국밥같은 말씀 잘 들었습니다! 모듈 분리의 의도를 잘 이해했습니다. 설계라는것도 두 관점으로 접근할 수 있는게, 하나는 점진적으로 필요할 때 마다 설계를 개선해나가는 방법이 있고, 또 다른 하나는 예측이 되는 수준까지는 그 수준에 도달하기 전에 미리 구축해 놓는 방법이 있다고 생각합니다. 물론 심적으로는 전자를 조금 더 선호하나, 제가 경험했던 실무 환경에서는 가용 리소스나 유지보수, 그리고 참여하는 팀원들의 선호도를 고려했을 때 후자를 선택해서 진행하는 경우가 많았습니다. 특히 경험이 많은 시니어의 탄탄한 설계는 생산 효율성을 극대화 하여 업무에 많은 도움을 주었습니다. 한가지 아쉬운 점이 있다면 이번 미션이 모듈 설계나 멀티모듈을 경험하기 위해 설계된 미션이 아니다보니 실질적으로 이렇게 모듈 설계를 했을 때 얻어갈 수 있는 경험이 제한적이라는 점 입니다. 그리고 앞서 드린 질문은 향후 미션 수행과 리뷰어와의 소통에 큰 영향을 줄 수 있다고 생각합니다. |
브라운 안녕하세요!
미션 리뷰를 받기 전에, 실무를 하면서 멀티 모듈에 대한 고민을 많이 했습니다.
실무에 멀티 모듈 형식의 프로젝트를 진행하기 전에 미션에서 적용해보면서 공부하고 싶어서 적용하게 되었습니다.
미션 외의 리뷰이지만 브라운의 생각과 의견을 들어보고 싶습니다. 😄
구조 자체를 변경하다 보니 코드 수정이 매우 많습니다... 😅
모듈은 아래와 같이 되어있습니다.
고민 했던 점은 아래와 같습니다.