SelfValidatable 을 만들어서 편하게 사용하자

유알·2024년 3월 7일
0

'만들면서 배우는 클린아키텍쳐' 책을 읽다가 SelfValidating 라는 객체를 만들어 쓰는 것을 보고, 조금 개선해서 코드 스니펫으로 남긴다

개선한 점은 다음과 같다

  • Factory를 static으로 한번만 생성하도록 변경 (객체 생성 비용 아끼기)
  • validate 메서드에서 예외를 직접 던지는게 아니라, Set을 리턴하도록 해서, 호출하는 쪽에서 적합한 예외를 선택할 수 있도록 변경
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;

import java.util.Set;

public abstract class SelfValidatable<T> {

    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private final Validator validator;

    protected SelfValidatable() {
        this.validator = factory.getValidator();
    }

    protected ValidateResult<T> validateSelf() {
        return new ValidateResult<>(validator.validate((T) this));
    }

    public static class ValidateResult<T>{
        private final Set<ConstraintViolation<T>> violations;

        public ValidateResult(Set<ConstraintViolation<T>> violations) {
            if (violations == null) {
                throw new IllegalArgumentException("violations must not be null");
            }
            this.violations = violations;
        }

        public boolean isValid() {
            return !violations.isEmpty();
        }

        public Set<ConstraintViolation<T>> getViolations() {
            return violations;
        }
    }
}

이 코드를 만들어 놓고, 상속해서 사용하면 된다. 뭐,, AOP 로 구현된 @Validated 같은거 써도는 되지만,
나의 경우, 모듈, 라이브러리를 설계할때 Spring Validation 디펜던시를 추가하기 좀 꺼려지는 경우가 있었다.(톰캣 디펜던시도 내장되어 있고,,)

profile
더 좋은 구조를 고민하는 개발자 입니다

0개의 댓글