패키지 구조를 어떤 것을 선호하시나요?
- 저는 기능별 패키지를 선호합니다.
- 저는 subway-map 미션에서 레이어별 패키지로 구현하였고, 이후 미션에서는 모두 기능별 패키지로 구현하였습니다.
- 장점
- 기능별 패키지를 통해 도메인을 중점으로 한 개발이 가능해졌습니다.
- 또한 해당 도메인을 사용하는 클래스들만을 하나의 패키지에 결집시켜 놓아 유지보수에도 편하겠다 생각이 들었습니다.
- 자연스레 기능별로 높은 응집도와 낮은 결합도를 갖게 되는 것 같습니다.
- 또한 나중에 기능별로 프로젝트를 분리하기 유리하다
- 단점
- Spark->Spring으로 옮겨올때 도메인이 모여있어 금방 옮겨왔었다
- 기능별 패키지는 이런 확장에 조금 어려움이 있다
웹 어플리케이션 구조에 대해 설명해주세요
- Controller는 사용자의 URL 엔드포인트로써, 사용자의 요청을 Dto로 매핑하고, 해당 요청을 처리할 서비스를 호출해줍니다.
- Service는 핵심 비즈니스 로직을 구현한 도메인과 DB의 접근을 통해 필요한 비즈니스 로직 처리를 진행합니다.
- Dao는 DB에 필요한 정보에 대한 CRUD 작업을 진행
왜 이렇게 분리해놨죠?
- 관심사의 적절한 분리를 통한 유지보수 용이
RequestDto를 Service까지 내려줘도 괜찮을까요?
- 나는 괜찮다고 생각한다.
- Dto가 결국 데이터 전송 객체이고, PresentationLayer와 ServiceLayer를 이어주는 다리로 생각한다
- 즉 Service까지 Dto가 내려오고 반환값으로 Dto를 Controller에게 주는것이 좋아보인다.
- 도메인 객체를 Presentation Layer로 부터 감추고 사용할 수 있게 하는 것이 최우선이라 생각
- 다만 Service가 Service를 의존하는 경우가 있는데, 이 경우 도메인을 넘겨주는 것은 괜찮아보인다.
예외 처리를 어떤 방식으로 진행했나요?
- 기능별로 Exception 패키지를 만들어, 해당 기능 사용시 발생할 수 있는 커스텀 예외를 정의해둡니다.
- 커스텀 예외에서는 예외 메시지만 정의해 두었습니다.
- 통일된 예외 메시지를 전달해주기 위해 ErrorResponse라는 객체를 생성
- ResponseEntity를 Controller가 반환하는데, body에 ErrorResponse를 담아서 보냄
- ResponseEntity에는 알맞은 Http-Status 코드를 넣어줬습니다.
- Jackson 라이브러리를 통해 해당 객체가 Json으로 변환되어 응답이 됩니다.
- @RestControllerAdvice와 @ExceptionHandler를 사용하여 예외를 잡아서 처리합니다.
- 마지막 미션에서는 각 기능별로 ControllerAdvice를 만들었습니다.
- 기능별로 잡아주기 위해 @RestControllerAdvice(basePackageClasses = StationController.class) 다음과 같이 basePackageClasses를 정의해 뒀었음
CheckedException UncheckedException 중 어떤것을 사용했나요?
- 저는 UncheckedException을 사용합니다.
- 어차피 @RestControllerAdvice에서 예외를 한데 잡아 처리할 것이라 약속이 되어있으니, 메서드 시그니처를 이용한 예외 위임은 필요없어 보인다.
- 오히려 메서드 시그니쳐를 써주면, interface로 추출하여 확장에 유리한 코드를 작성하는데 있어 방해가 될 것이라 생각합니다.