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};
}
}