목표
- 자신이 단 댓글, 좋아요는 알람이 가지 않도록 하기
- 좋아요 서비스 로직 메서드 분리
코드
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
이렇게 각각 조건문을 추가한 함수는 굉장히 길고 가독성이 좋지 않았다.
조금 더 깔끔하게 보는 것이 좋다고 생각들어 경우의 수마다 최대한 메서드를 나누어 분리해주었다.
아래의 세가지의 상황으로 메서드를 나누었다.
- 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 "좋아요를 눌렀습니다.";
}
해당 리펙토링을 진행하고 나서 로직을 나누어서 볼 수 있어서 이전과는 다르게 원하는 부분을 빠르게 수정하고 찾을 수 있었다.
'프로젝트 > SNS만들기' 카테고리의 다른 글
[SNS Project] Post 삭제 시 Like, Comment 삭제하기 (영속성 전이, Soft Delete) (0) | 2023.01.07 |
---|---|
[SNS Project] 마이피드 테스트 (0) | 2023.01.06 |
[SNS Project] 마이피드 기능 구현 (0) | 2023.01.06 |
[SNS Project] 좋아요 기능 - Soft Delete 리펙토링(@Modifying) (2) | 2023.01.06 |
[SNS Project] Post, User 예외처리 분리하기 (0) | 2023.01.04 |