20231221 (목) CourseRegistration 만들기

2023. 12. 21. 20:23TIL

어제에 이어 강의를 따라하면서 CourseRegistration 앱 만들기를 진행했다.

아직 결과물을 몰라서 뭐라고 말하긴 힘들지만 아마 HTML 배웠을때 처럼 웹사이트 형식으로 제작되는것 같다.

내가 제작할 것에 맞춰서 패키지를 분할하고, 분할한 패키지에서 필요한 요소를 하나하나 코딩하며 시간이 지나갔다.

일단은 강의를 따라하는 수준이라 크게 어렵거나 이해가 안되는 것은 없지만,

이걸 또 내가 원하는 방식으로 바꾸는것은 상당히 어려울것 같다.

 

CourseRegistration라고 강의를 듣기위해 회원가입을 하고 원하는 강의를 수강하는 형식인데,

도메인 패키지 안에서 유저, 강의, 강의안의 동영상, 강의신청, 예외처리 패키지를 나눴다.

 

유저

유저는 아마 튜터(영상제작), 학생(수강자) 로 나뉠것 같고, 본인 역할에따라 접근 가능한 범위도 다르게 설정할 예정이다.

강의코스

크게 강의 생성, 조회, 수정, 삭제로 이루어져있고 해당 강의안에 동영상은 따로 패키지를 분리해놨다.

강의영상

위와 비슷하게 영상 생성, 조회, 수정 ,삭제로 이루어져있다.

강의 신청

강의 목록 조회, 특정 강의 조회, 강의 신청, 신청 철회 등으로 이루어져있다.

예외처리

위의 모든 경우에 예외가 발생하면 알려주고 적절한 응답을 해주는 형식으로 이루어져있다.

 

일단 지금은 강의를 보면서 익숙해지도록 하고있고, 제출해야하는 본 과제는 할일카드 앱(TodoApp) 제작인데 위의 내용들을 이용하면서 만들어보도록 해야겠다.

 

모든 코드들을 올려두고 싶긴하지만 너무 길어질것 같아서 가장 중요해보이는 CourseServiceImpl 파일을 복사해서 올린다.

package com.example.courseregistration.domain.course.service

import com.example.courseregistration.domain.course.dto.CourseResponse
import com.example.courseregistration.domain.course.dto.CreateCourseRequest
import com.example.courseregistration.domain.course.dto.UpdateCourseRequest
import com.example.courseregistration.domain.courseapplication.dto.ApplyCourseRequest
import com.example.courseregistration.domain.courseapplication.dto.CourseApplicationResponse
import com.example.courseregistration.domain.courseapplication.dto.UpdateApplicationStatusRequest
import com.example.courseregistration.domain.exception.ModelNotFoundException
import com.example.courseregistration.domain.lecture.dto.AddLectureRequest
import com.example.courseregistration.domain.lecture.dto.LectureResponse
import com.example.courseregistration.domain.lecture.dto.UpdateLectureRequest
import jakarta.transaction.Transactional
import org.springframework.stereotype.Service

@Service
class CourseServiceImpl: CourseService {

    override fun getAllCourseList(): List<CourseResponse> {
        // TODO: DB에서 모든 Course 목록을 조회하여 CourseResponse 목록으로 변환 후 반환
        TODO("Not yet implemented")
    }

    override fun getCourseById(courseId: Long): CourseResponse {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 ID기반으로 Course 가져와서 CourseResponse로 변환 후 반환
        // TODO("Not yet implemented")
        throw ModelNotFoundException(modelName = "Course", id = 1L)
    }

    @Transactional
    override fun createCourse(request: CreateCourseRequest): CourseResponse {
        // TODO: request를 Course로 변환 후 DB에 저장
        TODO("Not yet implemented")
    }

    @Transactional
    override fun updateCourse(courseId: Long, request: UpdateCourseRequest): CourseResponse {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId에 해당하는 Course를 가져와서 request기반으로 업데이트 후 DB에 저장, 결과를 CourseResponse로 변환 후 반환
        TODO("Not yet implemented")
    }

    @Transactional
    override fun deleteCourse(courseId: Long) {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO :DB에서 courseId에 해당하는 Course를 삭제, 연관된 CourseApplication과 Lecture도 모두 삭제
        TODO("Not yet implemented")
    }

    override fun getLectureList(courseId: Long): List<LectureResponse> {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId에 해당하는 Course목록을 가져오고, 하위 lecture들을 가져온 다음, LectureResopnse로 변환해서 반환
        TODO("Not yet implemented")
    }

    override fun getLecture(courseId: Long, lectureId: Long): LectureResponse {
        // TODO: 만약 courseId, lectureId에 해당하는 Lecture가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId, lectureId에 해당하는 Lecture를 가져와서 LectureResponse로 변환 후 반환
        TODO("Not yet implemented")
    }

    @Transactional
    override fun addLecture(courseId: Long, request: AddLectureRequest): LectureResponse {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId에 해당하는 Course를 가져와서 Lecture를 추가 후 DB에 저장, 결과를을 LectureResponse로 변환 후 반환
        TODO("Not yet implemented")
    }

    @Transactional
    override fun updateLecture(courseId: Long, lectureId: Long, request: UpdateLectureRequest): LectureResponse {
        // TODO: 만약 courseId, lectureId에 해당하는 Lecture가 없다면 throw ModelNotFoundException
        /* TODO: DB에서 courseId, lectureId에 해당하는 Lecture를 가져와서
            request로 업데이트 후 DB에 저장, 결과를을 LectureResponse로 변환 후 반환 */
        TODO("Not yet implemented")
    }

    @Transactional
    override fun removeLecture(courseId: Long, lectureId: Long) {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId, lectureId에 해당하는 Lecture를 가져오고, 삭제
        TODO("Not yet implemented")
    }

    @Transactional
    override fun applyCourse(courseId: Long, request: ApplyCourseRequest): CourseApplicationResponse {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: 만약 course가 이미 마감됐다면, throw IllegalStateException
        // TODO: 이미 신청했다면, throw IllegalStateException

        TODO("Not yet implemented")
    }

    override fun getCourseApplication(courseId: Long, applicationId: Long): CourseApplicationResponse {
        // TODO: 만약 courseId, applicationId에 해당하는 CourseApplication이 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId, applicationId에 해당하는 CourseApplication을 가져와서 CourseApplicationResponse로 변환 후 반환
        TODO("Not yet implemented")
    }

    override fun getCourseApplicationList(courseId: Long): List<CourseApplicationResponse> {
        // TODO: 만약 courseId에 해당하는 Course가 없다면 throw ModelNotFoundException
        // TODO: DB에서 courseId에 해당하는 Course를 가져오고, 하위 courseApplication들을 CourseApplicationResponse로 변환 후 반환
        TODO("Not yet implemented")

    }

    @Transactional
    override fun updateCourseApplicationStatus(
            courseId: Long,
            applicationId: Long,
            request: UpdateApplicationStatusRequest
    ): CourseApplicationResponse {
        // TODO: 만약 courseId, applicationId에 해당하는 CourseApplication이 없다면 throw ModelNotFoundException
        // TODO: 만약 status가 이미 변경된 상태면 throw IllegalStateException
        // TODO: Course의 status가 CLOSED상태 일시 throw IllegalStateException
        // TODO: 승인을 하는 케이스일 경우, course의 numApplicants와 maxApplicants가 동일하면, course의 상태를 CLOSED로 변경
        // TODO: DB에서 courseApplication을 가져오고, status를 request로 업데이트 후 DB에 저장, 결과를 CourseApplicationResponse로 변환 후 반환
        TODO("Not yet implemented")
    }

}

 

지금까지 작성한 코딩중 대부분이 거쳐가는 파일인듯 싶다.

중간중간 @Transactional이 붙은 메소드들은 예외가 발생할 수 있는 것들이고, 예외가 발생하면 따로 응답을 할수 있도록 스프링 빈을 표시해 둔것이다.

 

사실 이렇게 한곳에 모아두는 형식의 코딩은 추천되지 않는다고 한다.(파일 하나의 부담이 너무 커져서라고 하셨던것 같다.)

일단 빠른코딩을 위해 지금은 이런식으로 만들되.. 만약 부담을 덜고싶다면 Lecture부분은 따로 LectureService 파일을 만들어서 나누는 방법도 나쁘지 않을것 같다.

 

오늘의 한마디 : 아직은 모든게 이해되지는 않지만, 당연한거라고 생각한다. 급해지지 말고 천천히 배워나가자