Backend/Java

[숫자야구게임 Step3] Repository 구현

Seyun(Marco) 2024. 9. 20. 22:34
728x90

서론

  • 이전 장에서는 숫자야구게임의 정책문서를 작성하며, 테크스펙을 작성해 개발시 문제가 될 영역들을 체크해봤다.
  • Step2에서 필요한 Reposiotry에서의 로직을 구현해보겠습니다.

GameRepository

  • 추상화를 위해 Inteface를 구현합니다.
package baseball.repository;

import baseball.domain.Game;

import java.util.List;
import java.util.Optional;

public interface GameRepository {
    int insert(Game game);

    Optional<Game> findById(int gameId);

    List<Game> findAll();

    List<Game> findAllByPlayerTimes(int playerTimes);

    int getMinPlayerTimes();

    int getMaxPlayerTimes();

    double getAveragePlayerTimes();

    void clear();

}

  • getMinPlayerTimes는 최소 횟수를 조회하는 메서드입니다.
  • getMaxPlayerTimes는 최대 횟수를 조회하는 메서드입니다.
  • getAveragePlayerTimes는 평균 횟수를 조회하는 메서드입니다.
  • findAllByPlayerTimes(int playerTimes)는 해당 횟수의 게임을 조회합니다.
    • 최소, 최대 횟수의 게임 목록을 조회해야 하기 때문에 실제 메서드가 필요합니다.
  • 이제 실제 구현체를 보겠습니다.
package baseball.repository;

import baseball.domain.Game;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class GameRepositoryImpl implements GameRepository {
    private static final Map<Integer, Game> GAME_RECORDS = new HashMap<>();
    private static int id = 1;

    @Override
    public int insert(Game game) {
        game.setId(id);
        GAME_RECORDS.put(id, game);
        id++;

        return game.getId();
    }

    @Override
    public Optional<Game> findById(int gameId) {
        return Optional.ofNullable(GAME_RECORDS.get(gameId));
    }

    @Override
    public List<Game> findAll() {
        return GAME_RECORDS.values()
                .stream()
                .toList();
    }

    @Override
    public List<Game> findAllByPlayerTimes(int playerTimes) {
        return GAME_RECORDS.values()
                .stream()
                .filter(game -> game.samePlayerTimes(playerTimes))
                .toList();
    }

    @Override
    public int getMinPlayerTimes() {
        return GAME_RECORDS.values()
                .stream()
                .mapToInt(Game::getPlayerTimes)
                .min()
                .orElse(0);
    }

    @Override
    public int getMaxPlayerTimes() {
        return GAME_RECORDS.values()
                .stream()
                .mapToInt(Game::getPlayerTimes)
                .max()
                .orElse(0);
    }

    @Override
    public double getAveragePlayerTimes() {
        return GAME_RECORDS.values()
                .stream()
                .mapToInt(Game::getPlayerTimes)
                .average()
                .orElse(0);
    }

    @Override
    public void clear() {
        GAME_RECORDS.clear();
    }

}

  • PlayerTimes를 Count라는 VO로 만들어났기 때문에 mapToInt를 활용하여 변환을 해야 화며, min, max, average 메서드를 각각 사용하여 최소, 최대, 평균 값을 구하면 됩니다.
  • 아울러 PlayerTimes를 활용하여 조회를 해야 하기 떄문에 처음으로 filter()를 사용하였습니다. filter()메서드란 실제 인자에 들어가는 조건을 충족하는 요소들을 추출하는 메서드입니다.
  • 이렇게 하여 모든 값들을 조회할수 있습니다.

결론

  • 이번엔 stream의 메서드들을 한번 써볼수 있는 기회였던거 같습니다.
  • steam을 잘 알고 있다면 쉽게 접근할 수 있는 영역들이였다고 생각이 듭니다.
  • 마지막 글에서는 실제 동작을 정의내려보도록 하겠습니다.
728x90
728x90