Skip to content
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

[2차] 서수민 과제 제출합니다. #13

Open
ssm00 opened this issue Oct 31, 2024 · 0 comments
Open

[2차] 서수민 과제 제출합니다. #13

ssm00 opened this issue Oct 31, 2024 · 0 comments
Labels
2차 과제 2차 과제입니다.

Comments

@ssm00
Copy link

ssm00 commented Oct 31, 2024

  • 해당 저장소의 ISSUE에 본인이 작업한 레포 주소와 과제 내용을 올려주세요!

이번 2차 과제에서는 수강신청 시스템에 핵심 기능들을 구현하고, TDD 방식을 적용하여 시스템의 신뢰성을 높이는 것을 목표로 합니다.

🥅 과제 목표

TDD(Test-Driven Development) 방식을 적용하여 수강신청 시스템의 주요 기능을 개발하고, 동시성 문제를 해결합니다

필수 구현 사항

선택 1. 수강신청 기능 구현

  • 학생이 수강신청을 추가할 수 있는 기능을 구현하세요.
  • 동일한 시간대에 중복으로 수강신청을 할 수 없도록 제한하세요.
    • 여러 학생이 동시에 동일한 강좌를 신청할 때 발생할 수 있는 문제를 고려해보세요!
  • 학생은 신청한 수강신청을 취소할 수 있어야 합니다.
  • 학생은 자신이 신청한 수강신청 목록을 조회할 수 있어야 합니다.

요구 사항

  • 학생은 동일한 강좌에 여러 번 신청할 수 없습니다!

선택 2. 강좌 목록 조회 기능 구현

  • 모든 사용자는 강좌 목록을 조회할 수 있어야 합니다.
  • 강좌 목록은 강의명, 강의 시간, 담당 교수, 수강 가능 인원수 등의 정보를 포함해야 합니다.
  • 수강신청 가능 상태(잔여 인원)에 따라 필터링할 수 있는 기능을 추가하세요.
    • 필터링 옵션은 수강 가능 강좌와 마감된 강좌로 나누어 제공하세요.
    • 강좌에는 capacity (정원)와 enrolled (수강 신청한 인원) 필드가 존재하며, enrolled < capacity인 경우 수강신청이 가능하다고 간주합니다.

요구 사항

  • 강좌 정보는 강의명, 강의 시간, 담당 교수, 수강 가능 인원수 등을 포함해야 합니다.

설계 가이드 예시

수강신청 정보

  • id
  • student_id
  • course_id
  • 신청 시간
  • 상태(신청 완료/취소)

강좌

  • id
  • 강좌명
  • 강의 시간
  • 담당 교수
  • 정원

3. 나의 이해와 의견

  • 각 기능을 TDD 방식으로 개발하면서 어떤 테스트를 먼저 작성했는지, 그리고 해당 테스트를 통과하기 위해 어떤 코드를 작성했는지에 대한 설명을 포함하세요.
    • 수강신청성공 → 수강신청인원초과 → 전체수강신청목록조회 → 내성공수강신청목록조회 → 동일한수강신청으로 구현 하였습니다.
    • given when then 방식으로 구현하였습니다.
    • given 절에서는 repository에 직접 접근하여 임의의 값을 넣습니다.
      • 처음에 Mockito를 사용하여 Repository를 생성하였으나 test.yaml 파일을 이용해 test 환경에서 h2 DB를 따로 생성하여 MOCK이 아닌 필드에 직접 Repository를 주입하는 방식으로 변경했습니다.
      • mock사용시 test코드를 mock에서 제공하는 메소드를 사용해야 하는점 때문에 test db가 분리되어 있는 경우 필드 주입을 사용하여 코드를 작성하는 것이 더 직관적으로 느껴졌습니다.
    • 처음에 Test 작성 시 service레이어 에서 Entity를 파라미터로 입력받는 방식으로 메서드 구현을 생각했습니다. 이후 DTO로 입력받는 방식이 맞다고 판단되어 이 부분을 수정하였습니다.
      • 테스트코드 작성과 동시에 대략적인 설계가 이루어져야 하는데 머리로 하는 대략적인 구현이 틀려 테스트 코드를 수정하는 일이 많았습니다.
    • given 절 작성 시 entityManager를 이용하여 flush와 clear를 진행해야 then절을 통과하는 경우를 생각해야했습니다.
      • 테스트의 경우 given과 then절이 하나의 메소드안에서 실행되기 때문에 given절의 데이터가 db flsuh가 진행되지 않아 when절 실행 시 영속성 컨텍스트에 있는 데이터가 연관관계가 설정 되지 않는 문제가 있었습니다.
      • 연관관계 편의 메소드를 사용하여 given절에서 연결 해 주는 방식과 entityManager를 이용해 flush와 close하는 방식이 가능했습니다.
      • 실제 비즈니스로직 에서는 Given의 데이터 입력과 then의 수강 신청 기능이 동시에 일어나지 않기 때문에 Test코드를 위해 연관관계 편의 메소드를 추가하는것 보다 실제 비즈니스로직 실행 흐름과 동일하게 Given 호출 후 flush를 한 뒤 then절을 실행하는것이 더 낫다고 생각하였습니다.
  • 동시성 문제를 해결하기 위한 방법과 그 과정에서의 어려움 또는 고민을 함께 서술해주세요.
    • Reddis를 사용해서 LOCK을 걸어 해결하였습니다.
    • Course ID를 이용하여 Redis가 lock을 생성할 때 과목 ID로 생성합니다 이후 같은 과목에 접근하는 경우 LOCK을 확인하여 동시적으로 코드가 실행되는것을 방지합니다.
    • optimistic(다른 요청이 동시에 들어오는 경우 ), pessimistic (데이터베이스에 성능 부하 락을 위해 커넥션을 계속 점유 커넥션 풀이 말라버릴 수 도있음), 방법이 있었지만 한번에 요청이 많이 몰리는 경우 Redis(메모리에서 빠르게 처리)를 사용하는 것이 장점이 있어서 채택하였습니다.

과제 리포지토리 : https://github.com/ssm00/unite_club_tdd

과제 제출 예시

ISSUE 제목: [2차] test1 과제 제출합니다.

@ssm00 ssm00 added the 2차 과제 2차 과제입니다. label Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2차 과제 2차 과제입니다.
Projects
None yet
Development

No branches or pull requests

1 participant