ReportService 클래스 코드 가독성 향상 (2023.05.19)
-
기존 코드의 문제점
- 변수의 재할당
- 변수에 담긴 표현식이 변수명과 다를 바 없음
- Optional 타입에 대해 get()을 사용해 NoSuchElementException 발생 위험
- 결재서류 정렬 변수 값(sortBy)이 상수이기 때문에 구분이 어려움
- equals()가 아닌 ==으로 값을 비교함
-
개선 후 코드
- 변수 초기화 후 재할당하는 상황을 없애기 위해 선언 후 if else 분기문에 따라 값이 할당되도록 변경
- 변수 인라인(Inline Variable)로 코드 간결하게 수정
- Optional 반환 타입에 대해 get() 대신 ifPresent()와 orElseThrow() 를 사용해 CustomException 발생시키도록 코드 수정
- ReportSortType enum class를 만들어 상수 대신 enumType으로 sortBy를 구분하기 쉽도록 변경
- == 대신 equals()로 값을 비교하도록 코드 수정
- 생성자로 객체를 생성할 때는 매개변수의 순서가 중요합니다. 또한 모든 데이터가 매개변수에 전달되어야 합니다. 객체 생성시 필요한 매개변수가 달라지면 그에 따라 생성자를 여러 개 만들어야 하는 불편함이 있습니다.
- 빌더 패턴은 필요한 데이터만 설정할 수 있고, 변수를 새로 추가해도 기존 코드에 영향을 주지 않습니다. 가독성을 높이고, 변경 가능성을 최소화할 수 있습니다.
- 이러한 장점이 있어 프로젝트에서는 DTO 사용 시 일괄적으로 빌더 패턴을 적용해 사용하고 있습니다. ReportDto 수정 시 이것이 적용되지 않은 부분이 있어 @Builder 어노테이션을 적용하도록 수정했습니다.
- @Data 어노테이션은 @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode 어노테이션을 모두 포함하기에 필요한 어노테이션만 사용하기 위해 이 어노테이션은 삭제하였습니다.
- 스프링이 JSON을 Object로 역직렬화 시 기본 생성자를 가지고 역직렬화하기 때문에, request 요청을 처리하는 DTO 클래스의 경우 @NoArgsConstructor를 적용하고, 다른 클래스에서 빈 객체를 생성하지 못하도록 private 레벨로 설정했습니다.
- @Builder 어노테이션을 클래스 단에 추가시 자동으로 @AllArgsConstructor(access=AccessLevel.PACKAGE)가 생성되는 효과가 있습니다. 또한 @NoArgsConstructor가 이미 선언되어 있는 경우 @AllArgsConstructor가 생성되지 않습니다. 빌더 패턴으로 DTO 객체를 생성할 것이기 때문에 AllArgsConstructor로 따로 객체를 생성할 수 없도록 AccessLevel을 private로 설정했습니다.
- ReportDto의 GetReportResponse에서는 본래 모든 필드를 매개값으로 갖는 생성자를 작성해 사용하고 있었으나, 빌더 패턴 적용으로 통일하게 되어 빌더로 DTO 객체를 생성해 반환하는 fromEntity라는 메서드를 사용하도록 변경하였습니다.
- fromEntity가 기존의 생성자와 같은 매개변수를 갖기 때문에 빌더 패턴의 매개변수의 순서와 상관없이 편리하게 사용할 수 있다는 장점을 활용하지 않는 방식이라는 생각이 들긴 합니다. 그러나 이미 작성된 코드들과 방식을 통일하기 위해 이 방식으로 작성하였습니다.