오늘은 분명 책상에 앉아서 책보고 공부하고, 개발을 6시간 이상 했는데.. 큰 결과물이 없다.. 6시간밖에 공부를 안한것도 레전드다.. 비때문인가.. 게을러졌다.. 몹시.. 늘어진다...그리고 늘어졌다.. 이러면안돼!!정신차려!!
Domain 개발
오늘은 DomainCore 개발을 모두 마치고, DomainApplication 을 개발하기 시작했다. DomainCore 의 DomainService 를 개발하면서 어떻게 이를 테스트해야할까? 하는 고민이 많았다.
테스트를 통한 개발을 진행하면서, 내가 기대하는 결과를 발생하도록 개발하는 것은 어렵지 않았다. 하지만, 항상 생각해야하는 예외상황에 대한 처리가 부족한듯했다. DomainService 에서 발생할 수 있는 예외는 무엇일까? 하는 고민을 많이 해봤다.
결론적으로 DomainService 는 도메인(Product) 내에 존재하는 도메인 로직을 캡슐화하는 서비스인데, 도메인서비스 내 특정 로직을 통해 유효성이 검사되므로 추가적인 예외처리는 필요가 없겠다는 생각이 들었다. 동시에, DomainService 가 그렇다면 필요할까? 하는 생각도 같이 하게되었는데, 이렇게 캡슐화를 해주는 것이 나는 필요하다 생각한다. 예상되는 동작으로 동작함을 확신할 수 있는 서비스라면, 이것이 진정 서비스의 역할을 톡톡히 하는 것이아닐까 하는 생각이다.
ProductApplicationService
다음 Domain-Application 을 개발하기 시작했다. 이번 Product 에서도 기존 Member 를 개발할 때와 크게 다른 점은 존재하지 않는다. 차이점이라고 한다면, 추적(조회)기능에 있어 좀더 세분화가 필요할 듯하다.
각 커맨드(혹은쿼리)는 CommandHandler 를 통해 각 유스케이스에 맞게 구현이 될 것 이다. 그리고 기존의 Member와는 다른 조회 기능은 크게 단품조회(세부사항확인), 제품 종류별 조회를 목표로 하였고, TrackQueryHandler 에서 각 세부사항을 구현할것 같다.
이것이 확정된 것은 아니다. 사실 interface를 사용하는 ApplicationServiceImpl 로서, 기능 추가 및 변경이 잦은 상황에서 추가될 기능들에 대한 선언부를 어느곳에 해야하는가에대한 큰 고민에 빠졌기 때문이다.. 나는 interface에 기능을 선언하고 해당 기능을 구현하는 방식을사용하고 있는데, 기능이 계속 추가 수정된다고하면, 한곳에서 추가를 하는 것이 아니라, 두곳에서 추가를 해야하는 것인가? 고민이다. 이것은 비효율적인것같다.
그래서 TrackQueryHandler 를 통해 해당 클래스 내에 조회에 대한 유스케이스를 세분화 하는 방법을 생각했는데, 이 또한 문제가 될 것 같다. TrackProductQuery 내 프로퍼티로 유스케이스를 구분해야한다는 것이 문제이다. null 값을 선언하지 않고 모든 유스케이스에 알맞도록 설계하는 것이 큰 관건이 될 것 같다.
일단 나는 ApplicationServiceImpl 의 틀만 잡아두고 각 Command(Query)를 구현하기 시작했다. 이번 Command(Query) 구현 간 가장 큰 목표는 입력 유효성 검사를 해당 Command(Query)안에 구현하는 것이다.
나는 기존의 Command(Query)가 생성된 후, 실질적으로 사용될 때 유효성 검사가 이뤄지는 것은 상당히 비효율적이라고 생각했다. 그리고 이번 Product 개발 간, 개선하고자 하였다.
이를 위해, 기존의 사용하던 @Builder, @AllArgsConstructor 어노테이션은 사용하지 않게 되었다. 그리고 유효성 검사로 Bean Validation API를 활용하기로 하였다.
먼저 나는 자가 입력 유효성 검사를 하기 위한 클래스를 생성했다.
SelfValidating 클래스를 상속하여 각 Command에서 validateSelf()를 수행할 수 있도록 하였다.
기존의 각 Command(Query)는 프로퍼티가 많아 @Builder 어노테이션을 통해 생성자 표기 없이 빌더 패턴을 사용할 수 있었다. 하지만 이번 Command의 입력 유효성을 검증하기 위해서는 생성자에서 검즘이 이뤄져야하기 때문에 Builder 플러그인을 사용하기도 결정하였다.
그리고 정상 테스트가 성공하는 것을 확인할 수 있었다. 하지만 다른 문제가 발생했다.
갑자기 멀쩡하던 MemberApplicationService 에서 문제가 발생했다.
실패 내역을 확인한 결과 전혀 뜬금없는 ConstraintViolationException이 발생했다. 하지만 이것은 뜬금 없는 것이 아닌, 내 실수로 인한 에러를 잡아낸 것이였다. 이번 Bean Validation API를 사용하면서, 의존성을 하나 추가했다.
implementation 'org.hibernate.validator:hibernate-validator'
그리고 의존성을 추가하면서, 기존 코드의 문제점을 파악할 수 있었다. 나는 ApplicationService 인터페이스에서 선언된 @Valid 가 정상적으로 작동하고 있는 줄 알았다. 하지만 아니였다. 이번 경험을 통해 빈약한 테스트를 작성했음을 알 수 있었다. 그리고 builder 패턴의 단점(?)을 알 수 있었다. 프로퍼티가 많을 때, 빌더를 통해 알맞은 프로퍼티에 필드를 선언하는 편리함을 얻었으나, 필드를 선언하는 것을 잊어버리는 치명적인 단점을 갖는다는 것이다. 그리고 이는 이전, 내가 만든 오류로 나를 괴롭히기도 했다.
Member 이 제대로 생성되지 않았다. 의 부분이 나를 그렇게 괴롭혔다.
예비군 훈련, SLASH, 테스트 문제
오늘은 예비군 훈련을 다녀왔다. 평소보다 여유롭게 6시 반에 기상하여 준비했다.(사실 그냥 더 자고싶어서 잤다..) 예비군은 진짜 조기퇴소 각이였는데.. 우리 분대가 90점,100점 받은 과목이, 평
sykeem.tistory.com
가장 효율적으로 이를 해결하는 방법은, 생성할 때, 입력 유효성을 검증하면 된다. 그리고 나는 SelfValidating 클래스를 통해 이 문제를 해결했다.
이렇게 정리하고 보니, 정말 간단한 내용들인데 하루가 다 지나갔다.. 쓰읍..... 조금만 더 부지런해지는걸 목표로.. 계속해서 나아가야겠다.
'회고 > TIL' 카테고리의 다른 글
이어지는 폭염, 그리고 공부 앤 공부 (0) | 2023.07.03 |
---|---|
ApplicationService(유스케이스) 구현과 고민 (7) | 2023.06.30 |
클린아키텍처, 유스케이스 구현하기 (0) | 2023.06.28 |
Product 테스트 작성, 좋은 테스트에 관하여, Member 피드백 (0) | 2023.06.27 |
Product 도메인 설계 및 개발 시작, 만들면서 배우는 클린아키텍처 (0) | 2023.06.26 |