미소를뿌리는감자의 코딩

[FightClub] getMatchHistory API 작성 본문

프로젝트

[FightClub] getMatchHistory API 작성

미뿌감 2024. 12. 29. 12:48
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