TemporaryPassword refactoring - leegwichan/StackOverFlow_Refactoring GitHub Wiki

โ—Ž ๊ธฐ์กด ์ž‘์„ฑ ๋ฐฉ๋ฒ•

  • ์ฝ”๋“œ์— ํ•„์š”ํ•œ ์š”์†Œ๋“ค์„ ์ƒ๊ฐ ๋‚˜๋Š”๋Œ€๋กœ ์ž‘์„ฑํ•จ
  • ๊ธฐ๋Šฅ ๊ตฌํ˜„์—๋งŒ ์ดˆ์ ์„ ๋งž์ถค

โ—Ž ๊ธฐ์กด ์ž‘์„ฑ ๋ฐฉ๋ฒ•์˜ ๋ฌธ์ œ์ 

  • ๋ณ€๊ฒฝ์„ ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์›€
    • method ํ•˜๋‚˜์—์„œ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋ณด๊ธฐ ํž˜๋“ฆ
    • ex) ๊ธฐ์กด์— ๋žœ๋ค ๋ฌธ์ž์— ๋Œ€๋ฌธ์ž๋„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด, ์ฝ”๋“œ์˜ ์ „๋ฐ˜์ ์ธ ๊ณผ์ •์„ ๋ชจ๋‘ ์ดํ•ดํ•˜๊ณ  ์ˆ˜์ •ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
  • method๊ฐ€ ์‹คํ–‰ ๋  ๋•Œ๋งˆ๋‹ค Random ๊ฐ์ฒด ์ƒ์„ฑ
  • return ๊ฐ’์ด String[]์œผ๋กœ ๋˜์–ด ์žˆ์–ด ๊ฐ๊ฐ์˜ Array ์นธ์ด ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ํ•œ๋ˆˆ์— ์•Œ ์ˆ˜ ์—†๋‹ค.

โ—Ž Refactoring ์ค‘์  ์‚ฌํ•ญ

  • method๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ๋‚˜๋ˆ”

    • method ํ•˜๋‚˜์—์„œ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ๋งŒ์„ ํ•˜๋„๋ก ๊ตฌ์„ฑํ•จ
    • method line์„ 15์ค„์ด ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ์ž‘์„ฑ
  • Random ๊ฐ์ฒด๋ฅผ class ํด๋ž˜์Šค ๋ณ€์ˆ˜๋กœ ์ƒ์„ฑํ•จ

    • Random ๊ฐ์ฒด๋ฅผ ํ•œ๋ฒˆ๋งŒ ์ƒ์„ฑํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉํ•จ
  • return ํ˜•์‹์„ PasswordDto๋กœ ํ•จ

    • PasswordDto๋ฅผ ๋งŒ๋“ค์–ด ๊ธฐ๋ณธ password ์ •๋ณด์™€ ์•”ํ˜ธํ™”๋œ password ์ •๋ณด๋ฅผ returnํ•จ
    • getter๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โ—Ž Refactoring ํšจ๊ณผ

  • ๋ณ€๊ฒฝ์— ๋งค์šฐ ์šฉ์ดํ•จ

    • ์ž„์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ์˜ ๊ธ€์ž ์ˆ˜๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด PASSWORD_LENGTH ์ˆ˜์ •
    • ์ž„์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ์— ๋“ค์–ด๊ฐ€๋Š” ๊ธ€์ž๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด createRandomLetter() ์ˆ˜์ •
  • return ํ˜•์‹์„ PasswordDto๋กœ ํ•˜๋ฉด์„œ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉ์‹œ ๊ฐ’์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

      @Override
      public void resetPasswordByEmail(String email) {
          Member findMember = findMemberByEmailExpectExist(email);
    
          PasswordDto newPassword = temporaryPassword.create();
          temporaryPasswordSender.send(email, newPassword.getDecodedPassword());
    
          findMember.updatePassword(newPassword.getEncodedPassword());
          memberRepository.save(findMember);
      }
    

โ—Ž ๋ณ€๊ฒฝ ์ดํ›„ ์ฝ”๋“œ

@Component
public class TemporaryPassword {

    private static final char START_LETTER = 'a';
    private static final char END_LETTER = 'z';
    private static final int PASSWORD_LENGTH = 10;

    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    private final Random random = new Random();

    public PasswordDto create(){
        String generatedPassword = createRandomPassword();
        String encodedPassword = encoder.encode(generatedPassword);

        return new PasswordDto(generatedPassword, encodedPassword);
    }

    private String createRandomPassword() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < PASSWORD_LENGTH; i++) {
            sb.append(createRandomLetter());
        }
        return sb.toString();
    }

    private char createRandomLetter() {
        int randomASCIICode = START_LETTER + random.nextInt(END_LETTER - START_LETTER);
        char randomLetter = (char) randomASCIICode;
        return randomLetter;
    }
}

@AllArgsConstructor
@Getter
public class PasswordDto {

    private String decodedPassword;
    private String encodedPassword;
}

โ—Ž ๋ณ€๊ฒฝ ์ด์ „ ์ฝ”๋“œ

@Component
@RequiredArgsConstructor
public class TemporaryPassword {

    private final BCryptPasswordEncoder encoder;

    public String[] create(){

        int leftLimit = 97; // letter 'a'
        int rightLimit = 122; // letter 'z'
        int targetStringLength = 10;
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < targetStringLength; i++) {
            int randomLimitedInt = leftLimit + (int)
                    (random.nextFloat() * (rightLimit - leftLimit + 1));
            sb.append((char) randomLimitedInt);
        }

        String generatedString = sb.toString();
        String encodeString = encoder.encode(generatedString);

        return new String[]{generatedString, encodeString};
    }
}