Skip to content

Latest commit

 

History

History
246 lines (205 loc) · 8.07 KB

CLASS_DIAGRAM.md

File metadata and controls

246 lines (205 loc) · 8.07 KB

CLASS DIAGRAM

콘서트 예약 클래스 다이어그램

전체 클래스 다이어그램

전체 클래스 다이어그램에선 파사드 위주로 작성하였습니다. (생략된 부분은 아래의 각 도메인 클래스 다이어그램을 참고해주세요.)

---
title: "콘서트 예약 클래스 다이어그램"
---

classDiagram
    class UserFacade {
        - userService: UserService
        + getWallet(userId: Long): Wallet
        + updateWallet(userId: Long, walletId: Long, amount: Integer, operationType: OperationType): Wallet
    }

    class WaitingQueueFacade {
        - WaitingQueueService: WaitingQueueService
        - userService: UserService
        + createWaitingQueue(): Long
        + getWaitingQueue(uuid: String): WaitingQueue
        + expireWaitingQueue(uuid: String): void
    }

    class ConcertFacade {
        - concertService: ConcertService
        - userService: UserService
        - waitingQueueService: WaitingQueueService
        + getAvailableConcertSchedules(concertId: Long): List~ConcertSchedule~
        + getAvailableConcertSeats(concertScheduleId: Long): List~ConcertSeat~
        + reserveConcertSeat(userId: Long, concertSeatId: Long): Reservation
        + payReservation(userId: Long, reservationId: Long): Payment
    }

    WaitingQueueService --> WaitingQueueFacade
    UserService --> ConcertFacade
    UserService --> WaitingQueueFacade
    UserService --> UserFacade
    ConcertService --> ConcertFacade
Loading

유저 도메인

---
title: "유저 도메인 클래스 다이어그램"
---

classDiagram
    class User {
        - userId: Long
        - name: String
    }

    class Wallet {
        - walletId: Long
        - userId: Long
        - amount: Integer
    }

    class UserService {
        - userRepository: UserRepository
        + getUser(userId: Long): User
        + getWallet(userId: Long): Wallet
        + updateWallet(userId: Long, walletId: Long, amount: Integer, operationType: OperationType): void
    }

    class UserRepository {
        <<interface>>
        + findById(userId: Long): User
        + findWalletByUserId(userId: Long): Wallet
        + save(balance: Balance): Long
    }

    User "1" -- "1" Wallet
    UserService ..> User
    UserService ..> Wallet
    UserRepository --> UserService
Loading

대기열 토큰 도메인

---
title: "대기열 토큰 도메인 클래스 다이어그램"
---

classDiagram
    class WaitingQueue {
        - waitingQueueId: Long
        - concertId: Long
        - uuid: String
        - status: WaitingQueueStatus
        - expiredAt: LocalDateTime
    }

    class WaitingQueueStatus {
        <<enumeration>>
        WAITING
        PROCESSING
        EXPIRED
    }

    class WaitingQueueService {
        - WaitingQueueRepository: WaitingQueueRepository
        + getWaitingQueue(WaitingQueueId: Long): WaitingQueue
        + getWaitingQueue(uuid: String): WaitingQueue
        + getWaitingQueuesExpiredAtBefore(now: LocalDateTime): List~WaitingQueue~
        + createWaitingQueue(): Long
        + updateWaitingQueueStatus(WaitingQueueId: Long, status: WaitingQueueStatus): void
    }

    class WaitingQueueRepository {
        <<interface>>
        + findById(WaitingQueueId: Long): WaitingQueue
        + findAllByExpiredAtBefore(now: LocalDateTime): List~WaitingQueue~
        + findByStatusOrderByIdDesc(status: WaitingQueueStatus): WaitingQueue
        + save(WaitingQueue: WaitingQueue): Long
    }

    WaitingQueue -- WaitingQueueStatus
    WaitingQueueService ..> WaitingQueue
    WaitingQueueRepository --> WaitingQueueService
Loading

콘서트 도메인

---
title: "콘서트 도메인 클래스 다이어그램"
---

classDiagram
    class Concert {
        - concertId: Long
        - title: String
        - description: String
    }

    class ConcertSchedule {
        - concertScheduleId: Long
        - concertId: Long
        - concertAt: LocalDateTime
        - reservationStartAt: LocalDateTime
        - reservationEndAt: LocalDateTime
    }

    class ConcertSeat {
        - concertSeatId: Long
        - concertScheduleId: Long
        - number: Integer
        - price: Integer
        - isReserved: Boolean
    }

    class Reservation {
        - reservationId: Long
        - userId: Long
        - concertSeatId: Long
        - status: ReservationStatus
        - reservedAt: LocalDateTime
    }

    class ReservationStatus {
        <<enumeration>>
        WAITING
        CONFIRMED
        CANCELED
    }

    class Payment {
        - paymentId: Long
        - reservationId: Long
        - userId: Long
        - amount: Integer
    }

    class ConcertService {
        - concertRepository: ConcertRepository
        + getConcert(concertId: Long): Concert
        + getConcertSchedule(concertScheduleId: Long): ConcertSchedule
        + getConcertSeat(concertSeatId: Long): ConcertSeat
        + getReservation(userId: Long, concertSeatId: Long): Reservation
        + getReservationsReservedAtBefore(now: LocalDateTime): List~Reservation~
        + updateConcertSeatReservation(concertSeatId: Long, isReserved: Boolean): void
        + createReservation(userId: Long, concertSeatId: Long): Long
        + createPayment(userId: Long, reservationId: Long): Long
    }

    class ConcertRepository {
        <<interface>>
        + findById(concertId: Long): Concert
        + findConcertScheduleById(concertScheduleId: Long): ConcertSchedule
        + findConcertSeatById(concertSeatId: Long): ConcertSeat
        + findAllReservationsByReservedAtBefore(now: LocalDateTime): List~Reservation~
        + save(concertSeat: ConcertSeat): ConcertSeat
        + save(reservation: Reservation): Reservation
        + save(payment: Payment): Payment
    }

    Concert "1" -- "1..*" ConcertSchedule
    ConcertSchedule "1" -- "1..*" ConcertSeat
    Reservation "1" -- "1" User
    Reservation "1" -- "1" ConcertSeat
    Reservation -- ReservationStatus
    Payment "1" -- "1" User
    Payment "1" -- "1" Reservation
    Concert <.. ConcertService
    ConcertSchedule <.. ConcertService
    ConcertSeat <.. ConcertService
    Reservation <.. ConcertService
    Payment <.. ConcertService
    ConcertRepository --> ConcertService
Loading

클래스 다이어그램 고려사항

  • 도메인은 유저, 대기열 토큰, 콘서트로 구성되며, 각 도메인은 서비스 계층을 통해 접근합니다.
  • 유저 도메인은 사용자 정보와 잔액을 관리하며, 잔액은 충전 및 차감이 가능합니다.
  • 대기열 토큰 도메인은 사용자의 대기열 순서를 관리하며, 대기열 토큰은 만료 시간을 가집니다.
  • 콘서트 도메인은 콘서트 정보, 콘서트 일정, 좌석 정보, 예약 정보, 결제 정보를 관리합니다.

대기열 토큰

  • 대기열 토큰의 경우 상태 에 따라 대기 중인지, 처리 중인지, 만료된 상태인지를 나타내며, 만료 시간을 가집니다.
  • 대기열 상태가 처리 중인 경우에 접근이 가능하다고 판단합니다.
  • 대기열 상태가 처리 중으로 바뀔때 만료시간 시간을 설정하여 만료시간이 지나게 되면 만료된 상태로 변경됩니다.

잔액

  • 잔액의 경우 충전 및 차감이 가능하며, 충전 및 차감 시에는 잔액을 업데이트 합니다.
  • 잔액의 경우 User와 1:1 관계를 가지며, User가 삭제되면 잔액도 함께 삭제됩니다.
  • User와 같은 생명주기이며 User가 에그리거트 루트로 잔액을 관리합니다.

콘서트

  • 콘서트의 경우 콘서트 정보, 콘서트 일정, 좌석 정보, 예약 정보, 결제 정보를 관리합니다.
  • 좌석에 대해 예약 및 결제가 진행됩니다.
  • 좌석의 경우 isReserved로 예약 여부를 확인할 수 있으며 isRserved가 true가 되는 시점에 Reservation이 생성됩니다.
  • 예약이 완료되면 결제가 진행되며, 결제가 완료되면 좌석이 소유권이 확정됩니다.
  • 일정시간 동안 결제가 완료되지 않으면 예약이 취소됩니다.
  • 좌석의 경우 충돌이 많이 발생하지만 예약이 완료된 시점에 나머지 요청은 취소되기에 낙관적 락 방식을 고려합니다.