현재 내 프로젝트의 Layerd Architecture 전통적인 3계층을 따르고있다.
Presentaion Layer
⬇️
Business Layer
⬇️
Persistence Layer
이러한 계층형 아키텍쳐를 설계한 이유의 첫번째는 테스트 코드 작성을 중요하게 여겨서다.
계층별로 관심사를 분리하면 테스트 코드 작성이 쉬워진다.
특히 Presentaion Layer인 Controller의 단위 테스트를 작성할 때 3계층 아키텍처를 고려하지않고
무분별하게 프로덕션 코드를 작성했다면 Service Class뿐아니라 Persistence Layer들의 객체까지도 Mocking했어야할것이다.
그런데,
최근 계층형 아키텍쳐에대해 공부하며 내 개인 프로젝트를 만들며 문제점을 발견했다.
나의 개발 방향성을 지속적으로 확장시킬수 있는 생명주기가 긴 웹 어플리케이션을 만들자 이지만
프로젝트 코드를 보며 놓치고있던점을 발견했다.
Business Layer 즉 Service Class에서 너무 많은 클래스들을 의존하고있다는점.
기존의 나의 Service Class는 이렇다.
@PostMapping("posts")
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
public ResponseEntity<PostsResponse> createPosts(@AuthenticationPrincipal CustomUserPrincipal userPrincipal,
@RequestBody @Validated CreatePostsRequest request){
PostsResponse posts = postsService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(posts);
}
이미 리팩토링을 마치고 커밋에 푸쉬까지 다해서 다시 예전 코드를 작성함...
Presentaion Layer 에서 받은 DTO가
Business Layer인 Service까지 내려가 사용됬던것.
또한 ServiceClass Method에서 Entity를 return하고있어 Persistence Layer의 객체가 Presentaion Layer 까지 쩜프를 뛰어버린 상황
계층형 아키텍쳐를 설계해놓고 정작 실제코드는 계층형을 싹다 무시해버린 상태....
날을 잡고 컨트롤러부터 리팩토링을 시작했다.
컨트롤러는 Presentaion Layer로 외부 요청과의 접근이 많은 클래스이기에 최대한 Layer간 뛰어넘기를 방지하며 리팩토링을 진행했다.
최초로 외부 요청으로 도착한 request를 Controller request로 설정하고
Controller DTO에서 Business Layer의 ServiceDTO로 변환하여 넘겨줘
Presentaion Layer 하위 계층인 Business Layer가 Presentaion Layer를 의존하지 않도록 바꿔줬다.
또한 BusinessLogic에서 요청에 따른 Entity생성을 진행할 때
이런식으로 Entity Class에서 상위 계층의 DTO를 받아 엔티티를 생성했는데
Persistence Layer에 속한 Entity의 의존성을 줄이기위해 Entity 내부에서 생성하지않고
ServiceDTO내에서 toEntity를 통해 Entity를 생성 후 save()를 진행했다.
이런식으로 계층간의 의존성을 줄여
상위 계층의 변경이 생기더라도 하위 계층의 영향이 없도록해 좀 더 확장성있고 변화에 유연한 프로젝트로 리팩토링을 진행했다.
import를 통해 Service Class가 Controller의 Class를 의존하지않다는것을 쉽게 확인 할 수 있게됬다.
현재 프로젝트의 어떻게 더 계층간의 의존성을 줄이고 응집도를 높일 수 있을까 고민하면서
다음 리팩토링의 목적은 Service Class에서 Spring Security의 의존성을 줄여가기
Business Layer의 Service Class 하나에 모든 로직을 다 때려박지않고 Spring Security 관련 business logic들만 수행하는 Service Class를 만들어 진행해볼 예정이다...
다만 현재 구현해야할 기본 기능들이 많이 밀려있어서 최소한의 프로젝트 완성이 된 후 진행하기로!
'Project > TomorrowLand' 카테고리의 다른 글
Testable Code 작성을 위한 노력 1 (0) | 2024.01.11 |
---|---|
테스트 케이스를 작성하지말자. (0) | 2024.01.11 |
조회수 동시성문제 비관적 Lock을 선택한이유. (0) | 2024.01.08 |
JWT를 이용한 로그인 기능 구현을하며 (0) | 2023.12.25 |
@WebMvcTest에 대한 고민 (0) | 2023.12.14 |