[Java]특강 신청 API 만들기 - 의식의 흐름 + 테이블 설계

nana·2024년 9월 29일
0

Spring

목록 보기
5/9

요구사항

✨특강 신청 API

  • 특정 userId 로 선착순으로 제공되는 특강을 신청하는 API 를 작성합니다.
  • 동일한 신청자는 동일한 강의에 대해서 한 번의 수강 신청만 성공할 수 있습니다.
  • 특강은 선착순 30명만 신청 가능합니다.
  • 이미 신청자가 30명이 초과되면 이후 신청자는 요청을 실패합니다.

특강 선택 API

  • 날짜별로 현재 신청 가능한 특강 목록을 조회하는 API 를 작성합니다.
  • 특강의 정원은 30명으로 고정이며, 사용자는 각 특강에 신청하기전 목록을 조회해볼 수 있어야 합니다.

특강 신청 여부 조회 API

  • 특정 userId 로 신청 완료된 특강 목록을 조회하는 API 를 작성합니다.
  • 각 항목은 특강 ID 및 이름, 강연자 정보를 담고 있어야 합니다.
  • 각 기능 및 제약 사항에 대해 단위 테스트를 반드시 하나 이상 작성하도록 합니다.
  • 다수의 인스턴스로 어플리케이션이 동작하더라도 기능에 문제가 없도록 작성하도록 합니다.
  • 동시성 이슈를 고려 하여 구현합니다.

Point.

  • 정확하게 30명의 사용자에게만 특강을 제공할 방법을 고민해 볼 것.
    => 여러명이 들어와도 순차적으로 신청을 허용하여 30명이 되면 끊어야함. : DB락을 걸어야 할듯..?
  • 같은 사용자에게 여러 번의 특강 슬롯이 제공되지 않도록 제한할 방법을 고민해 볼 것.
    => Lock을 어디에 걸지..고민이 필요한데.. 강의에 걸어야겠지?

테이블 설계

필요한 테이블

목표 : 최대한 간단하게 만들기 / 필요없는 컬럼 없애기

1) 특강 테이블 (lecture)

  • LECTURE_ID
  • LECTURE_NM
  • ENROLL_START_DATE
  • ENROLL_END_DATE => 기간이 필요하다고 생각해서 넣었지만 필요없을지도
  • CAPACITY
  • INSTURCTURE

2) 학생 테이블 (student)

  • STUDENT_ID
  • STUDENT_NM
  • APPLY_YN

3) 특강 히스토리(lecture_history)

  • HISTORY_SEQ
  • STUDENT_SEQ
  • LECTURE_SEQ
  • REG_DATE
  • REMAIN_CAPACITY (남은 자리? 필요할까?)

나중에 바뀔 수도 있겠지만 초안은 이러하다..
수용인원인 capacity는 사실 30명이라는 정원이 정해져 있기 때문에 없어도 되지만 현업에서 모든 강의에 30명을 한정해 놓는 경우는 없으니 그냥 한번 컬럼으로 제어해 보고싶어 넣었다.

reg_date에 대한 타입 고민도 했는데 실제 수강신청은 초 단위를 다루다 보니 history에 날짜만 들어가는 date보다 초 단위로 들어가는 datetime타입이 낫겠다고 생각했다.

그리고 날짜별로 현재 신청 가능한 특강 목록을 조회하라는 요구사항이 있었으므로 신청가능한 시작날짜와 종료 날짜를 넣어주었다.
(아 뭐지.. 이거 지금 회사의 컬럼과 굉장히 유사한 느낌이나서 PTSD가 오려고한다..ㅋㅋ;;)

✅ ERD 설계 무료 웹 사이트

Draw.io
ERD Cloud


프로젝트 구조

목표

이번 프로젝트의 목적은 Clean Architecture구조로 짠 코드로 TDD테스트를 진행하는 것이다.
아키텍처와 테스트 코드 작성에 집중하여 견고하고 유연한 서버 개발을 지향한다.

Clean Architecture

  • 비즈니스 로직이 핵심!
  • 데이터 계층 및 API 계층이 비즈니스 로직을 의존한다. (UseCase & Port 패턴)
  • 도메인 중심적인 고수준의 관심사 분리
  • DIP(Dependency Inversion Principle) 의존관계 역전 OK
  • OCP(Open Closed Principle) 개방 폐쇄 원칙 OK - 확장에 열려있어야한다.

그렇다면 처음부터 구조를 잘 잡는게 매우 매우 중요!!!!

FACADE PATTERN (파사드패턴)

퍼사드 패턴(Facade Pattern)은 구조 패턴(Structural Pattern)의 한 종류로써, 복잡한 서브 클래스들의 공통적인 기능을 정의하는 상위 수준의 인터페이스를 제공하는 패턴이다.

  • 퍼사드 객체(Facade Object)는 서브 클래스의 코드에 의존하는 일을 감소시켜 주고, 복잡한 소프트웨어를 간단히 사용 할 수 있게 간단한 인터페이스를 제공해준다.

  • 퍼사드 패턴을 통해 서브 시스템(SubSystem)들 간의 종속성을 줄여줄 수 있으며, 퍼사드 객체를 사용하는 곳(Client)에서는 여러 서브 클래스들을 호출할 필요 없이 편리하게 사용할 수 있다.

퍼사드 패턴 특징

패턴 사용 시기

시스템이 너무 복잡할때
그래서 간단한 인터페이스를 통해 복잡한 시스템을 접근하도록 하고 싶을때
시스템을 사용하고 있는 외부와 결합도가 너무 높을 때 의존성 낮추기 위할때

패턴 장점

하위 시스템의 복잡성에서 코드를 분리하여, 외부에서 시스템을 사용하기 쉬워진다.
하위 시스템 간의 의존 관계가 많을 경우 이를 감소시키고 의존성을 한 곳으로 모을 수 있다.
복잡한 코드를 감춤으로써, 클라이언트가 시스템의 코드를 모르더라도 Facade 클래스만 이해하고 사용 가능하다. 

💡Tip
외부에서 내부 로직을 직접 사용하기 떄문에 내부 로직의 구조를 변경한다고 하거나 파라미터나 리턴값 등을 변경할 경우 직접적으로 영향을 받아 수정이힘들거나 불가능한 경우가 종종 있다. 하지만 중간에 매개체 역할을 해주는 퍼사드 객체가 있기 때문에 실제 내부 로직이 어떻게 변경이 되더라도 상관이 없어지므로 의존성이 감소된다.

패턴 단점

퍼사드가 앱의 모든 클래스에 결합된 God 객체가 될 수 있다
퍼사드 클래스 자체가 서브시스템에 대한 의존성을 가지게 되어 의존성을 완전히는 피할 수는 없다.
어찌되었건 추가적인 코드가 늘어나는 것이기 때문에 유지보수 측면에서 공수가 더 많이 들게 된다.
따라서 추상화 하고자하는 시스템이 얼마나 복잡한지 퍼사드 패턴을 통해서 얻게 되는 이점과 추가적인 유지보수 비용을 비교해보며 결정하여야 한다.

코치님의 사전 발제 시간에 주신 팁으로 Facade Pattern을 언급하셔서 해당 패턴을 사용해 보기로 했다.

그럼 음..
수강신청이라는 Service를 하나 놔두고 A학생이 '파사드'라는 강의 수강신청 시에 이루어지는 행위들
1. A학생의 신청 여부(apply_yn)변경 Y->N
2. A학생의 신청 히스토리 추가
를 Facade 패턴으로 이용해야겠다.

수강신청 Service에 LectureHistory / Lecture / Student 서비스들을 캡슐화❌ 추상화⭕하는 것.

참고
Facade Pattern
💠-퍼사드Facade-패턴-제대로-배워보자

profile
BackEnd Developer, 기록의 힘을 믿습니다.

0개의 댓글