-
Notifications
You must be signed in to change notification settings - Fork 207
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
Step3 수강신청(DB 적용) #320
Step3 수강신청(DB 적용) #320
Conversation
- SessionState 메시지 전달 - SessionPeriod 시작 및 종료날짜 검증 - EnumSource 활용 - Session 생성 메소드 추출 - isSameBy 테스트 케이스 추가
- 유저가 강의를 중복 신청시 예외처리
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.
안녕하세요 우철님
요구사항에 맞게 잘 구현해 주셔서 예상하신 것보다 코멘트가 적네요 😃
다음 단계 전에 코멘트 확인 부탁드려요
마지막 단계 화이팅입니다 🔥
```mermaid | ||
--- | ||
title: lms | ||
--- | ||
erDiagram |
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.
diagram 👍
public Session(Long id) { | ||
this(id, null, null, null, null, null, null, null, null); | ||
} |
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.
테스트에서만 사용되는 생성자네요 😃
null 초기화보단 기본 값을 할당해줘도 좋을 것 같아요
private static void validateDateRange(LocalDate startDate, LocalDate endDate) { | ||
if (startDate.isAfter(endDate)) { | ||
throw new SessionPeriodException("시작일은 종료일 보다 작아야 합니다."); | ||
} | ||
} |
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.
피드백 반영👍
private static void validateDateRange(LocalDate startDate, LocalDate endDate) { | |
if (startDate.isAfter(endDate)) { | |
throw new SessionPeriodException("시작일은 종료일 보다 작아야 합니다."); | |
} | |
} | |
private void validateDateRange(LocalDate startDate, LocalDate endDate) { | |
if (startDate.isAfter(endDate)) { | |
throw new SessionPeriodException("시작일은 종료일 보다 작아야 합니다."); | |
} | |
} |
public void register(NsUser user, Payment payment) { | ||
validateState(); | ||
validateType(); | ||
validatePriceEqualPayment(payment); | ||
sessionUsers.addUser(user); | ||
sessionUserCount.plusUserCount(); | ||
} |
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.
유저 중복 신청을 막기 위해 Session내 SessionUsers를 만들었습니다. 해당 구조가 올바른지 확신이 들진 않네요..
잘 구현하신 것 같아요 👍
다만 지금처럼 기능이 추가되거나 변경되면 필드도 추가되고 메서드 내부도 계속 늘어날 것 같은데요
수강신청 객체를 도출해서 관련 책임들을 모두 위임하는 구조도 고려해 보시면 좋을 것 같아요
public void register(NsUser user, Payment payment) { | |
validateState(); | |
validateType(); | |
validatePriceEqualPayment(payment); | |
sessionUsers.addUser(user); | |
sessionUserCount.plusUserCount(); | |
} | |
public void register(NsUser user, Payment payment) { | |
enrollment.enroll(user, payment); | |
} |
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.
확실히 위임하니 더 좋네요!! 감사합니다~
price int not null, | ||
state varchar(10) not null, | ||
type varchar(10) not null, | ||
user_count int default 0, |
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.
user_session 테이블의 데이터 건수를 참조해도 될 것 같은데요
어떤 부분에서 user_count 컬럼이 필요하다고 판단하셨는지 궁금합니다
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.
😱 헉 그 생각을 못했네요..
불필요한 필드여서 지우는게 좋겠네요. 감사합니다!
SessionUsers sessionUsers = sessionUsersRepository.findBy(sessionId); | ||
Session session = sessionRepository.findBy(sessionId, sessionUsers) | ||
.orElseThrow(() -> new SessionException("강의 정보를 찾을 수 없습니다.")); | ||
session.register(user, payment); |
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.
조회한 SessionUsers를 Session 생성과 같은 생명 주기로 생성하고 싶었습니다
session 조회 시 sessionUsers를 모두 포함하는 형태를 원하셨다면
sessionRepository 내부에서 sessionUserRepository를 활용해 보셔도 될 것 같아요
public class JdbcSessionRepository implements SessionRepository {
private final SessionUserRepository sessionUserRepository;
...
public Optional<Session> findBy(long sessionId) {
final SessionUsers sessionUsers = sessionUsersRepository.findBy(sessionId);
...
}
}
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.
테스트코드에서 SessionUsersRepository
를 주입 못받아서 스킵했었는데
@import({JdbcSessionUsersRepository.class}) 방법이 있었네요..!
감사합니다~
primary key (id) | ||
); | ||
|
||
create table user_session |
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.
코드에서는 sessionUser 라는 이름으로 사용되고 있으니 테이블명도 같은 형식이면 좋을 것 같아요
작성하신 erd에도 session_user 라고 되어 있어요
primary key (id) | |
); | |
create table user_session | |
primary key (id) | |
); | |
create table session_user |
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.
h2에서 SESSION_USER 이게 예약어 더라구요 ㅠㅠ
session_users로 테이블명 수정하겠습니다~!
@Test | ||
@DisplayName("실패 - 유저가 기존에 신청한 강의일 경우 중복으로 수강 신청을 할 수 없다.") | ||
void fail_session_register_user() { | ||
Session session = zeroAndOneThousandSession(SessionState.OPEN, SessionType.PAID); | ||
assertThatThrownBy(() -> duplicateAddSessionRegister(session)) | ||
.isInstanceOf(SessionUserException.class) | ||
.hasMessage("강의를 이미 신청한 유저이므로 중복으로 신청할 수 없습니다."); | ||
} |
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.
개행을 활용해 단락을 구분하면 메서드 분리 없이도 가독성을 챙길 수 있을 것 같은데 어떻게 생각하시는지 궁금합니다
@Test | |
@DisplayName("실패 - 유저가 기존에 신청한 강의일 경우 중복으로 수강 신청을 할 수 없다.") | |
void fail_session_register_user() { | |
Session session = zeroAndOneThousandSession(SessionState.OPEN, SessionType.PAID); | |
assertThatThrownBy(() -> duplicateAddSessionRegister(session)) | |
.isInstanceOf(SessionUserException.class) | |
.hasMessage("강의를 이미 신청한 유저이므로 중복으로 신청할 수 없습니다."); | |
} | |
@Test | |
@DisplayName("실패 - 유저가 기존에 신청한 강의일 경우 중복으로 수강 신청을 할 수 없다.") | |
void fail_session_register_user() { | |
Session session = zeroAndOneThousandSession(SessionState.OPEN, SessionType.PAID); | |
final Payment payment = paymentOneThousand(); | |
session.register(JAVAJIGI, payment); | |
assertThatThrownBy(() -> session.register(JAVAJIGI, payment)) | |
.isInstanceOf(SessionUserException.class) | |
.hasMessage("강의를 이미 신청한 유저이므로 중복으로 신청할 수 없습니다."); | |
} |
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.
좋은 것 같습니다!! 감사합니다 ㅎㅎ
assertThat(users).hasSize(2) | ||
.extracting("id") | ||
.containsExactly(1L, 2L); |
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.
repository 테스트 코드 검증시 조회한 도메인 모델의 데이터를 모두 getter로 꺼내서 검증 해야 할까요?
위와 같은 필요성을 느끼질 못해서 id 혹은 테스트와 관련된 데이터만 검증했습니다..!
지금처럼 필요한 값 위주로 검증해 주셔도 될 것 같아요 😃
import java.util.Optional; | ||
|
||
public interface SessionRepository { | ||
Optional<Session> findBy(long sessionId, SessionUsers sessionUsers); |
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.
Optional 👍
용주님 안녕하세요.!!
수강신청(DB 적용) 리뷰 요청 드립니다.
이번 단계는 전 단계들보다 많이 헤맸네요..
아래는 질문 사항 입니다.!!
=> 위는 2차 리뷰 피드백 주신건데요!! 유저 중복 신청을 막기 위해 Session내 SessionUsers를 만들었습니다. 해당 구조가 올바른지 확신이 들진 않네요..
repository 테스트 코드 검증시 조회한 도메인 모델의 데이터를 모두 getter로 꺼내서 검증 해야 할까요?
위와 같은 필요성을 느끼질 못해서 id 혹은 테스트와 관련된 데이터만 검증했습니다..!
조회한 SessionUsers를 Session 생성과 같은 생명 주기로 생성하고 싶었습니다만.. 아래와 같은 코드로 구현을 하긴 했는데 도저히 아닌 것 같지만 올바른 방법이 떠오르질 않네요 ㅠㅠ JPA를 사용시 일급 컬렉션을 많이 쓰던데 그건 어떻게 가져오는건지 참..
이번 단계는 피드백 20개 정도 받을 것 같네요 ㅎ_ㅎ 🤑
이번 Step에서도 많이 배우겠습니다.
감사합니다. :)