cround-team / cround-server

크리에이터와 크리에이터를 꿈꾸는 사람들을 위한 커피챗 서비스
https://cround-client.vercel.app/
2 stars 1 forks source link

[REFACTOR] 메일 기능의 코드를 개선한다. #141

Open ahn-sj opened 1 year ago

ahn-sj commented 1 year ago

기능 설명

1) 메일 전송 속도를 개선하기 위해 비동기(Async)를 도입한다

비밀번호 찾기에 쓰이는 메일 전송은 하나의 메시지를 보내는데에 평균 4초(일반적으로 최소 3초, 최대 5초)가량의 시간이 소모된다.

image

따라서 동기/비동기의 차이를 명확히 이해하고 Async를 도입해 비즈니스의 속도를 향상시키도록 한다.


2) 메일(MailServiceImpl) 구현 클래스에서 코드 개선점을 찾아본다.

메일 기능이 확장됨을 고려해 내부 클래스로 MailType을 정의해놓았다.

@Service
@RequiredArgsConstructor
@Slf4j
public class MailServiceImpl implements MailService {

    @Override
    @Transactional
    public void send(String email, String type) {...}

    @Getter
    @AllArgsConstructor
    public enum MailType {

        PASSWORD(PASSWORD_CHANGE_SUBJECT_MESSAGE) {
            @Override
            public String appendText(Long id, String code) {
                return ... + "?id=" + id + "&code=" + code + "'>\uD83D\uDC49 비밀번호 재설정하기</a><br/><br/>";
            }
        };

        private final String text;

        public static MailType getMailType(String type) {
            return MailType.valueOf(type.toUpperCase());
        }

        public abstract String appendText(Long id, String code);
    }
}

Enum에 다형성을 부여해 추상 메서드를 오버라이딩 하는 식의 구현을 했지만
1) 메일 기능이 훨씬 더 확장될 경우 낮은 가독성 2) HTML을 만들어내는 하드 코딩된 코드 가 존재하고 있다.

해결방법 - 1: 개발 환경에서 쓰는 Java 버전이 11이기 때에 람다식인 BiFunction으로 개선 해결방법 - 2: HTML 코드와 인자에 따른 문자열 조합이 필요하기 때문에 적절한 디자인 패턴이 있는지 확인한다.


3) 메일 전송 악용에 대비한다

현재 코드에서 예상되는 악용 가능한 상황이 존재한다.

따라서 해당 경우에 대비해 캐시 등을 활용해서 최근 전송에 관한 상태를 추가하고 검증을 추가한다.
상태 값의 후보는 두 가지가 있다.

적절한 상황에 맞추어 구현하도록 한다.