미소를뿌리는감자의 코딩
[FightClub] getMatchHistory API 작성 본문
728x90
이번에 해당 API를 작성하고 코드를 보니, 너무 길어서 ChatGPT에게 어떻게 개선할 수 있을 지 물어보았다.
그랬더니 아래와 같이
- stream()
- filter()
- map()
- collect()
가 사용됨을 확인할 수 있다.
return user.getUserMatches().stream()
.filter(userMatch -> isValidMatch(userMatch, todayDate))
.map(userMatch -> createMatchSummaryDto(userMatch, user))
.collect(Collectors.toList());
- stream() 이란 데이터를 하나씩 순차적으로 처리할 수 있도록 해주는 Java의 기능
- filter() 는 userMatch -> isValidMatch( userMatch, todayDate) 를 만족하는 요소만 남기게 하는 메서드이다.
- map() 은 스트림의 각 요소를 다른 형태로 변환하는 메서드. 이는 userMatch 객체를 createMatchSummaryDto 함수에 전달해서, MatchSummaryDto 객체로 변환. 따라서, 새로운 형태의 객체로 바꾸는 역할.
- collect() 스트림의 요소들을 최종적으로 수집. Collectors.toList()를 통해 객체들의 리스트로 결과를 수집.
확실이 코드가 기능 분리가 되어서 깔끔한 맛이 살았다.
앞으로도, stream()을 적극적으로 이용하려 노력해봐야 겠다.
package com.sparta.fritown.domain.service;
import com.sparta.fritown.domain.dto.match.MatchInfo;
import com.sparta.fritown.domain.dto.match.MatchSummaryDto;
import com.sparta.fritown.domain.entity.Matches;
import com.sparta.fritown.domain.entity.Round;
import com.sparta.fritown.domain.entity.User;
import com.sparta.fritown.domain.entity.UserMatch;
import com.sparta.fritown.domain.entity.enums.Status;
import com.sparta.fritown.domain.repository.MatchesRepository;
import com.sparta.fritown.domain.repository.UserRepository;
import com.sparta.fritown.global.exception.ErrorCode;
import com.sparta.fritown.global.exception.custom.ServiceException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class MatchService {
private final UserRepository userRepository;
public List<MatchSummaryDto> getMatchHistory(Long userId) {
// 현재 유저 정보 가져오기
User user = userRepository.findById(userId)
.orElseThrow(() -> ServiceException.of(ErrorCode.USER_NOT_FOUND));
LocalDate todayDate = LocalDate.now();
return user.getUserMatches().stream()
.filter(userMatch -> isValidMatch(userMatch, todayDate))
.map(userMatch -> createMatchSummaryDto(userMatch, user))
.collect(Collectors.toList());
}
private boolean isValidMatch(UserMatch userMatch, LocalDate todayDate) {
Matches matches = userMatch.getMatches();
return matches.getDate().isBefore(todayDate) && matches.getStatus().equals(Status.DONE);
}
// MatchSummaryDto 생성 메서드
private MatchSummaryDto createMatchSummaryDto(UserMatch userMatch, User currentUser) {
Matches matches = userMatch.getMatches();
List<Round> rounds = userMatch.getRounds();
// 라운드 데이터 계산
MatchInfo matchInfo = calculateMatchInfo(rounds, matches.getDate());
// 상대 유저 찾기
User opponent = getOpponent(matches, currentUser);
// MatchSummaryDto 생성
return new MatchSummaryDto(matches.getId(), matchInfo, opponent.getNickname());
}
// MatchInfo 계산 로직 분리
private MatchInfo calculateMatchInfo(List<Round> rounds, LocalDate matchDate) {
int totalKcal = 0;
int totalHeartBeat = 0;
int totalPunchNum = 0;
int roundNums = rounds.size(); // 이걸로 리스트 길이 확인 가능.
for (Round round : rounds) {
totalKcal += round.getKcal();
totalHeartBeat += round.getHeartBeat();
totalPunchNum += round.getPunchNum();
}
int avgHeartBeat = roundNums > 0 ? totalHeartBeat / roundNums : 0;
return new MatchInfo(totalKcal, avgHeartBeat, totalPunchNum, roundNums, matchDate);
}
// 상대 유저 찾기
private User getOpponent(Matches matches, User currentUser) {
return matches.getChallengedBy().equals(currentUser)
? matches.getChallengedTo()
: matches.getChallengedBy();
}
}
728x90
'프로젝트' 카테고리의 다른 글
[FightClub] Openvidu 2.30을 통한 중계 서버 생성 (0) | 2025.01.05 |
---|---|
[FightClub] S3 Bucket 적용 - 이미지 업로드 (1) | 2024.12.29 |
[Fight Club] Global Handler 설정 - ExceptionHandler (1) | 2024.12.21 |
[Aper] Mono Repo library 적용 (0) | 2024.11.22 |
[Aper] 채팅 목록 반환 w. read status feat (0) | 2024.11.08 |