수진개발서

목표

- 자신이 단 댓글, 좋아요는 알람이 가지 않도록 하기
- 좋아요 서비스 로직 메서드 분리

코드

LikeService(이전 코드)

public String controlLike(Long postId, String userName) {
        //유저와 게시물의 존재 유무 확인
        ValidateUserPostDto validateUserPost = validateService.validateUserPost(userName, postId);

        //like db에 user과 post가 같은게 존재하는지 확인
        Optional<Like> like = likeRepository.findByUserAndPost(validateUserPost.getUser(), validateUserPost.getPost());
        //좋아요를 처음 누를 경우
        if (!like.isPresent()) {
            likeRepository.save(Like.toEntity(validateUserPost.getPost(), validateUserPost.getUser()));

            Alarm alarm = Alarm.toEntity(AlarmType.LIKE, validateUserPost.getUser(), validateUserPost.getPost());
            alarmRepository.save(alarm);
            return "좋아요를 눌렀습니다.";

        //이미 좋아요 및 취소를 누른 적 있는 경우
        }else{
            //deletedAt 기록 확인
            LocalDateTime likeDeleteAt = like.get().getDeletedAt();

            //좋아요 취소
            if (likeDeleteAt == null) {
                Optional<Alarm> alarm = alarmRepository.cancelAlarm(AlarmType.LIKE.getAlarmType(), validateUserPost.getUser().getId(), validateUserPost.getPost().getId());
                if (alarm.isPresent()) {
                    alarmRepository.delete(alarm.get());
                }
                likeRepository.delete(like.get());

                return "좋아요를 취소했습니다.";

                //다시 좋아요 누르기
            } else {
                likeRepository.reSave(like.get().getId());
                //알람 저장
                Alarm alarm = Alarm.toEntity(AlarmType.LIKE, validateUserPost.getUser(), validateUserPost.getPost());
                alarmRepository.save(alarm);
                return "좋아요를 눌렀습니다.";

            }

        }
    }

좋아요의 알람을 가게 할 때 자기 자신이 좋아요를 누른 경우에도 알람이 가는 상황이였다.
하지만 sns는 자신이 아닌 타인의 댓글과 좋아요에 알람이 가는 것이 맞다고 판단되어 수정해주었다.

//본인이 아닐경우 알람에 저장
if(validateUserPost.getUser().getId() != validateUserPost.getPost().getUser().getId()) {
    alarmRepository.save(alarm);
}

validateUserPost는 로그인 된 User와 해당 Post에 관한 정보를 담고있다.
유저와 작성자가 일치하지 않는다면 알람이 발생되도록 조건문을 추가해주었다.
자세한 클래스를 확인하고 싶다면 아래의 포스팅을 참고하면 된다.
https://alcoholble.tistory.com/6

 

[SNS Project] Post, User 예외처리 분리하기

목표 SNS만들기 프로젝트를 진행하면서 모든 로직에 공통적으로 들어가는 부분이 있었다. 아래와 같이 token에서 추출한 userName이 존재하는지, 접속한 게시물이 존재하는지 예외처리하는 로직이

alcoholble.tistory.com

이렇게 각각 조건문을 추가한 함수는 굉장히 길고 가독성이 좋지 않았다.
조금 더 깔끔하게 보는 것이 좋다고 생각들어 경우의 수마다 최대한 메서드를 나누어 분리해주었다.
아래의 세가지의 상황으로 메서드를 나누었다.

  • Like에 데이터가 없음(좋아요를 처음 누른 경우)
  • Like에 데이터가 있음 - delete_at에 데이터가 있음(좋아요 취소)
  • Like에 데이터가 있음 - delete_at에 데이터가 없음(좋아요)

각자 필요한 like, alarm, validateUserPost를 파라미터로 받아, 결과는 String으로 반환하도록 하였다.

LikeService(수정 코드)

    /**
     * 좋아요 및 좋아요 취소
     */
    public String controlLike(Long postId, String userName) {
        //결과 메세지
        String resultMessage;

        //유저와 게시물의 존재 유무 확인
        ValidateUserPostDto validateUserPost = validateService.validateUserPost(userName, postId);

        //like db에 user과 post가 같은게 존재하는지 확인
        Optional<Like> like = likeRepository.findByUserAndPost(validateUserPost.getUser(), validateUserPost.getPost());

        //알람 데이터 생성
        Alarm alarm = Alarm.toEntity(AlarmType.LIKE, validateUserPost.getUser(), validateUserPost.getPost());

        //좋아요를 처음 누를 경우
        if (!like.isPresent()) {
            resultMessage = firstPressLike(alarm, validateUserPost);

        //이미 좋아요 및 취소를 누른 적 있는 경우
        }else{
            //알람 기록 확인
            Optional<Integer> deleteAlarm = alarmRepository.cancelAlarm(AlarmType.LIKE.getAlarmType(), validateUserPost.getUser().getId(), validateUserPost.getPost().getId());

            //좋아요 취소
            if (like.get().getDeletedAt() == null) {
                resultMessage = cancelLike(like, deleteAlarm);

            //다시 좋아요 누르기
            } else {
                resultMessage = pressLike(like, validateUserPost, deleteAlarm);
            }
        }
        return resultMessage;
    }

    /**
     * 좋아요를 처음 누를 경우
     */
    public String firstPressLike(Alarm alarm, ValidateUserPostDto validateUserPost){
        //좋아요
        likeRepository.save(Like.toEntity(validateUserPost.getPost(), validateUserPost.getUser()));

        //본인이 아닐경우는 알람에 저장
        if(validateUserPost.getUser().getId() != validateUserPost.getPost().getUser().getId()) {
            alarmRepository.save(alarm);
        }
        return "좋아요를 눌렀습니다.";
    }

    /**
     * 좋아요 데이터 존재 - 좋아요 취소
     */
    public String cancelLike(Optional<Like> like, Optional<Integer> deleteAlarm){
        if (deleteAlarm.isPresent()) {
            alarmRepository.deleteById(deleteAlarm.get());
        }
        likeRepository.delete(like.get());
        return "좋아요를 취소했습니다.";
    }

    /**
     * 좋아요 데이터 존재 - 좋아요
     */
    public String pressLike(Optional<Like> like, ValidateUserPostDto validateUserPost, Optional<Integer> deleteAlarm){
        likeRepository.reSave(like.get().getId());
        //본인이 아닐경우는 알람에 저장 - deleteAt null값으로 바꾸기
        if(validateUserPost.getUser().getId() != validateUserPost.getPost().getUser().getId()){
            alarmRepository.reSave(deleteAlarm.get());
        }
        return "좋아요를 눌렀습니다.";
    }

해당 리펙토링을 진행하고 나서 로직을 나누어서 볼 수 있어서 이전과는 다르게 원하는 부분을 빠르게 수정하고 찾을 수 있었다.

profile

수진개발서

@sujin_park0607

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!