본문 바로가기
PlayGround/마실가실 리팩토링

[1년 후 마실가실] SonarQube와 Immutable List

by HJ0216 2024. 11. 22.

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

https://kr.pinterest.com/pin/578431145923739290/

(이미지와는 크게 상관없는 내용인데, 귀여워서 넣어봤습니다.)

 

여러분은 모르셨겠지만, 최근에 얼추 갖춰진 회원 CRUD가 끝났습니다.. 야호..

아직도 수정해야할 건 산더미이긴 하지만, 부담갖지 않고 해보고싶은 것들, 궁금한 것들을 위주로 리팩토링을 하자,, 라고 마음을 다지고 있습니다🚀.

 

지금은 큰 산이라고 생각한 이미지를 시작해보기 전에 코드를 좀 다듬는 중입니다.

 

그래서 이번에는 조금 간단한 내용으로 정적분석도구 SonarQube를 어떻게 쓰고 있는지를 짧게 남겨보고자 합니다.

 

SonarQube 사용하기

 

GlobalExceptionHandler.java
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
	  private ErrorResponse makeErrorResponse(BindException e, ErrorCode errorCode) {
    List<ErrorResponse.ValidationError> validationErrorList = e.getBindingResult()
                                                               .getFieldErrors()
                                                               .stream()
                                                               .map(
                                                                   ErrorResponse.ValidationError::of)
                                                               .collect(Collectors.toList());

    return ErrorResponse.builder()
                        .code(errorCode.name())
                        .message(errorCode.getMessage())
                        .errors(validationErrorList)
                        .build();
  }
}

 

* e.getBindingResult()

  * 회원 가입 시, 응집도를 높이기 위해 어노테이션을 사용해 각 필드값의 유효성 검사를 수행

    이 때, 유효성 검사에 실패할 경우, 해당 결과가 BindningResult에 저장

 

* getFieldErrors()

  * 유효성 검증에서 실패한 필드 단위의 오류 목록을 반환

  * FieldError 객체들로 구성된 List<FieldError>

[
  FieldError(field="email", rejectedValue="invalid@", message="Invalid email format"),
  FieldError(field="password", rejectedValue="123", message="Password is too short")
]

 

* stream()

  * 컬렉션 또는 배열과 같은 데이터를 함수형 프로그래밍 스타일로 처리할 수 있도록 지원하는 데이터 처리 도구

  * 가독성, 확장성 등을 위해서 해당 리스트를 stream으로 변환

// 일반
List<ValidationError> validationErrorList = new ArrayList<>();
for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
    validationErrorList.add(ValidationError.of(fieldError));
}

// Stream
List<ValidationError> validationErrorList = e.getBindingResult()
                                             .getFieldErrors()
                                             .stream()
                                             .map(ValidationError::of)
                                             .toList();

 

* map(ErrorResponse.ValidationError::of)

  * 기존 데이터의 각 요소를 가공하거나 다른 타입으로 변경할 때 사용

  * 스트림의 각 FieldError 객체를 ErrorResponse.ValidationError.of()를 사용하여 ErrorResponse.ValidationError 객체로 변환

 

* (기존) collect(Collectors.toList())

  * Collectors.toList(): mutable List(수정 가능한 리스트)를 반환

  * Validation Error는 한 번 발생한 이후, 수정될 가능성이 없으므로 Immutable List로 반환하는 것이 더 안정적

  * Java16 이상에서는 Stream.toList() / Java10 이상에서는 Collectors.toUnmodifiableList()로 Immutable List로 사용 가능

 

불변 리스트를 사용하여,

  1. 해당 코드의 의도를 명확히하고 

  2. 수정 작업이 불가능하므로 멀티 스레드 환경에서 동기화 작업에 들어가는 비용을 낮춰, 멀티스레드 환경에서 더 높은 성능과 낮은 복잡도를 제공

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료