-
Optional을 올바르게 활용해보기프로젝트/게시판 프로젝트 2022. 5. 24. 09:31
Optional이란?
간단하게 말하자면 값이 null일 수도 아닐 수도 있는 객체입니다.
즉, null이 될 수도 있는 객체를 포장해주는 Wrapper Class입니다.
여기까지만 읽었을 때 이해가 되지 않는다면 다음 글을 읽고 오면 좋습니다.
기존의 코드
@Override public boolean login(MemberLoginRequestDTO memberLoginRequestDTO) { Optional<Member> userId = memberRepository.findByUserId(memberLoginRequestDTO.getUserId()); //Optional 사용했으니 isPresent 대신 userId.orElseThrow()를 쓰는게 좋아보인다 if(!userId.isPresent()){ return false; } return userId.get().getPassword().equals(memberLoginRequestDTO.getPassword()); }
기존의 코드는 Optional을 사용하였지만 isPresent를 사용했습니다.
이렇게 사용하면 userId != null으로 사용하는 것과 크게 다를 것이 없습니다.
리팩터링 한 코드
static boolean result; @Override public boolean login(MemberLoginRequestDTO memberLoginRequestDTO) { Optional<Member> userId = memberRepository.findByUserId(memberLoginRequestDTO.getUserId()); userId.ifPresent((member) -> { result = member.getPassword().equals(memberLoginRequestDTO.getPassword()); }); return result; }
ifPresent 메서드를 활용하여 userId가 존재한다면 패스워드 검증을 통해 true, false를 result에 기록하도록 하였습니다.
또한 내부의 result값을 전달하기 위해서 전역 변수인 result를 선언하였습니다.
하지만 동시성을 고려해 보았을 때 많은 문제가 있습니다.
1번 공유되는 result 변수에 만약 2개의 사용자가 동시에 들어와서 다른 사용자의 true 값을 들고 로그인해버리는 경우가 발생할 수 있습니다.
1번 사용자는 아이디와 패스워드가 일치하여 result = true로 변환시키고 2번 사용자는 존재하지 않는 아이디를 입력하여서 바로 return result가 되는데 이때 원래라면 false가 반환되어야 하는데 true가 반환될 수 있습니다.
또한 userId 대신에 userId를 통해 member를 조회하여 Member 객체를 가져오기 때문에 user라는 변수명을 사용하는 것이 바람직해 보입니다.
다시 리팩토링한 코드
@Override public boolean login(MemberLoginRequestDTO memberLoginRequestDTO) { Optional<Member> user = memberRepository.findByUserId(memberLoginRequestDTO.getUserId()); String userPassword = user.orElseThrow(() -> new IllegalArgumentException()) .getPassword(); return BCrypt.checkpw(memberLoginRequestDTO.getPassword(), userPassword); }
orElseThrow 메서드를 사용하여 만약 user가 Null이라면 IllegalArgumentException을 발생시키고 그렇지 않으면 비밀번호를 얻어와서 Bcrypt.checkpw를 통해 암호화된 비밀번호와 입력받은 비밀번호를 검사합니다
Optional을 잘 이용하고 가독성이 높은 코드가 되었습니다.
결론
최근 꾸준히 람다식을 공부하고 있는데 프로젝트에 잘 적용해보고 싶습니다.
'프로젝트 > 게시판 프로젝트' 카테고리의 다른 글
뉴스 정보를 가져와 보자(크롤링, 네이버 뉴스 API 사용법) (0) 2022.05.25 JWT란? JWT 원리, 사용법 (0) 2022.05.24 비밀번호를 암호화 하자! (0) 2022.05.19 intellij 자동 포맷팅 시 줄 바꿈 처리 적용해주기 (0) 2022.05.19 로그인 기능을 만들어보자 (0) 2022.05.18