TIL

내일배움캠프 TIL 23.

phonebee 2025. 2. 21. 20:04

▶CH6 Spring 심화 개인 과제

※ 리펙토링이란?

● 리펙토링은 결과의 변경 없이 코드의 구조를 재조정한다는 의미이다.

 

※ 리펙토링은 왜 하는가?

● 코드의 가독성을 높인다.

● 유지보수를 편하게 한다.

 

그런 의미에서 레벨 1-1을 풀어보자

 

▷ Level 1-1 코드 개선 퀴즈 - Early Return

@Transactional
public SignupResponse signup(SignupRequest signupRequest) {

    String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());

    UserRole userRole = UserRole.of(signupRequest.getUserRole());

    if (userRepository.existsByEmail(signupRequest.getEmail())) {
        throw new InvalidRequestException("이미 존재하는 이메일입니다.");
    }

    User newUser = new User(
            signupRequest.getEmail(),
            encodedPassword,
            userRole
    );
    User savedUser = userRepository.save(newUser);

    String bearerToken = jwtUtil.createToken(savedUser.getId(), savedUser.getEmail(), userRole);

    return new SignupResponse(bearerToken);
}

해당 코드에서 아래의 코드를 리펙토링 하겠다.

if (userRepository.existsByEmail(signupRequest.getEmail())) {
    throw new InvalidRequestException("이미 존재하는 이메일입니다.");
}

 해당 애러가 발생하는 상황일 때, passwordEncoder의 encode() 동작이 불필요하게 일어나지 않도록 코드를 개선해달라는 것이 이번 문제의 목표이다.

 

조건으로는 signup() 메서드 안에서만 리펙토링을 진행하는 것이다.

 

우선 리팩토링을 하기 전 해당 코드가 실행되는 순서를 파악하자

 

signup 메서드가 실행되게 되면 우선,

String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());

가 실행되게 된다. 그 후

UserRole userRole = UserRole.of(signupRequest.getUserRole());

가 실행되고

if (userRepository.existsByEmail(signupRequest.getEmail())) {
    throw new InvalidRequestException("이미 존재하는 이메일입니다.");
}
User newUser = new User(
        signupRequest.getEmail(),
        encodedPassword,
        userRole
);
User savedUser = userRepository.save(newUser);
String bearerToken = jwtUtil.createToken(savedUser.getId(), savedUser.getEmail(), userRole);
return new SignupResponse(bearerToken);

순으로 코드가 실행되고 값을 반환한다.

 

코드 순서를 봤을 때, 문제에서 언급한 encode()가 우선적으로 실행되고 있다.

문제에서 언급한 에러가 발생하는 상황이면

String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());

UserRole userRole = UserRole.of(signupRequest.getUserRole());

if (userRepository.existsByEmail(signupRequest.getEmail())) {
    throw new InvalidRequestException("이미 존재하는 이메일입니다.");
}

코드는 여기까지 실행되고 throw를 통해서 예외 처리를 하기 위해 InvalidRequestException으로 던져진다.

즉, signup()메서드는 여기까지 실행한 후 예외처리로 이동하게 된다.

그럼, 예외가 발생할 때 encode() 동작이 불필요하게 일어나지 않으려면 코드를 어디로 이동시켜야하는가?

 

그렇다, encode()가 실행되는 코드 보다 앞에 위치하면 된다.

@Transactional
public SignupResponse signup(SignupRequest signupRequest) {

    //encode()가 먼저 실행되지 않기 위해서 이메일 중복 예외처리를 먼저 실행
    //해당 코드에서 예외처리를 실행 경우 InvalidRequestException로 예외를 던지고 그 밑의 코드는 수행을 하지 않기 때문에 해당 코드를 먼저 작성해야한다.
    if (userRepository.existsByEmail(signupRequest.getEmail())) {
        throw new InvalidRequestException("이미 존재하는 이메일입니다.");
    }

    String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());

    UserRole userRole = UserRole.of(signupRequest.getUserRole());

    User newUser = new User(
            signupRequest.getEmail(),
            encodedPassword,
            userRole
    );
    User savedUser = userRepository.save(newUser);

    String bearerToken = jwtUtil.createToken(savedUser.getId(), savedUser.getEmail(), userRole);

    return new SignupResponse(bearerToken);
}

encode()보다 앞에 위치하게 되면 예외처리를 먼저 진행하기 때문에 뒤에 있는 encode()가 실행이 되지 않는다.

그리고 코드가 제대로 실행되더라도 코드의 결과는 변하지 않기에 리펙토링을 했다고 할 수 있다.

'TIL' 카테고리의 다른 글

내일배움캠프 TIL 25.  (0) 2025.02.26
내일배움캠프 TIL 24.  (0) 2025.02.24
뉴스피드 프로젝트 트러블 슈팅 TIL  (0) 2025.02.20
CH3 일정 관리 앱 Develop 과제 TIL  (0) 2025.02.12
내일배움캠프 TIL 22.  (1) 2025.02.05