Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step2 진짜 누누 사칭 아님 #10

Open
wants to merge 60 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
88af85d
[1단계 - 웹 자동차 경주] 누누(송은우) 미션 제출합니다. (#19)
be-student Apr 17, 2023
51c1a5a
feat: domain 에 id 필드 추가
be-student Apr 18, 2023
933e02e
feat: entity 를 테이블과 1:1 매핑이 되도록 변경
be-student Apr 18, 2023
85e7fac
refactor: dao 는 entity 를 통해서 소통하고, repository 는 domain 을 통해서 처리하도록 변경
be-student Apr 18, 2023
1e23155
refactor: domain 생성 방식 id 도 고려하도록 변경
be-student Apr 18, 2023
4bf370a
chore: 컨트롤러 responseEntity 반환시 체이닝으로 변경
be-student Apr 18, 2023
8addd8f
fix: test 단계에서 rollback 되도록 transactional 개념 추가
be-student Apr 18, 2023
9a02622
fix: scannerClose 부분 제거
be-student Apr 18, 2023
67f7d15
feat: findAll repository 에서 기능 추가
be-student Apr 18, 2023
b4723d0
feat: findAll api 추가
be-student Apr 18, 2023
7c81776
feat: console 과의 중복 로직 제거
be-student Apr 18, 2023
9ef86e6
refactor: service 에서 도메인을 반환하도록 변경
be-student Apr 18, 2023
b36198f
refactor: service 를 useCase 별로 분리
be-student Apr 18, 2023
1d146ad
docs: 기능 목록 작성
be-student Apr 18, 2023
5c67368
test: findAllService 테스트 추가
be-student Apr 18, 2023
3d7aa7f
chore: 사용하지 않는 주석 제거
be-student Apr 18, 2023
4c5e606
feat: consoleApplication을 spring으로 실행시키도록 변경
be-student Apr 20, 2023
cb7a0b3
feat: 모듈 생성
be-student Apr 20, 2023
7a8d57a
feat: 모듈에 맞게 코드 위치 변경
be-student Apr 20, 2023
f197614
fix: 깨진 테스트 수정
be-student Apr 20, 2023
f7688f3
fix: root 경로에서 build 가능하도록 변경
be-student Apr 20, 2023
3d4123c
chore: 안 쓰이는 코드 제거
be-student Apr 20, 2023
c8aec85
chore: 메서드 네이밍 변경
be-student Apr 20, 2023
fa79391
feat: 출력 형식 변경
be-student Apr 20, 2023
cf4b01c
chore: 사용하지 않는 주석 제거
be-student Apr 20, 2023
9476e21
chore: 주석 제거
be-student Apr 20, 2023
15e2189
feat: console 에서 service 를 호출하도록 변경
be-student Apr 20, 2023
79fa2f1
test: outputView 테스트 작성
be-student Apr 20, 2023
e25246b
test: mapperTest 추가
be-student Apr 20, 2023
d50b28f
docs: 모듈간 의존성 작성
be-student Apr 21, 2023
9947c62
feat: SprintBootTest randomPort 에서 자동 drop 추가
be-student Apr 21, 2023
3e4f186
feat: vo 에 equals and hashcode 재정의
be-student Apr 21, 2023
b057296
feat: entity 에서 id 를 클래스로 관리하도록 변경
be-student Apr 21, 2023
b08ca4a
chore: 메서드 네이밍 변경
be-student Apr 21, 2023
ff72cdc
feat: 예외에 대한 logger 작성
be-student Apr 21, 2023
33df83e
test: dynamic test 작성
be-student Apr 21, 2023
f1cc1cc
feat: controller slice test 작성
be-student Apr 21, 2023
e7a1951
test: controller 잘못된 요청에 400 검증 추가
be-student Apr 21, 2023
40a329e
chore: 이름 변경
be-student Apr 21, 2023
c37e302
feat: domain 의 game 을 gameId 를 통해서 관리
be-student Apr 21, 2023
266f0ce
fix: 깨진 테스트 수정
be-student Apr 21, 2023
6533917
chore: 테스트 코드 정리
be-student Apr 21, 2023
54b1c9b
feat: post 생성 후 201 반환하도록 변경
be-student Apr 21, 2023
aa24bba
test: 패키지에 맞게 test 파일 재배치 및 dao 테스트 작
be-student Apr 21, 2023
2a681ad
test: 도메인 테스트 작성
be-student Apr 21, 2023
b4a8d4f
chore: 네이밍 변경
be-student Apr 21, 2023
8c20bc6
feat: application module 생성
be-student Apr 23, 2023
0a055fd
feat: racingGame 의 findWinner 에서 Winners를 반환하도록 변경
be-student Apr 23, 2023
86fa264
chore: 변수명 변경
be-student Apr 23, 2023
24c889a
feat: winners 객체를 바탕으로 저장하는 기능 추가
be-student Apr 23, 2023
7c5a732
chore: 메서드 네이밍 변경
be-student Apr 23, 2023
d263e95
feat: gameEntity 에 createdAt 추가
be-student Apr 23, 2023
77c6e69
fix: application.yml 위치 변경
be-student Apr 23, 2023
985ca7a
chore: 안 쓰이는 data.sql, application.yml 제거
be-student Apr 23, 2023
4b1a66e
chore: 쓸모 없는 메인 파일 제거
be-student Apr 23, 2023
d20a060
chore: 오타 수정
be-student Apr 23, 2023
bd0f76d
chore: 안 쓰이는 변수 제거
be-student Apr 23, 2023
e6ad7c7
fix: log 에서 빼먹었던 부분 제거
be-student Apr 23, 2023
cf774d6
fix: 깨지는 테스트 수정
be-student Apr 23, 2023
2511690
feat: h2 일때만 truncate 가 작동하도록 변경
be-student Apr 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
# jwp-racingcar

## ✔ 2단계 기능 요구사항

- [x] GET /plays 를 통해 지금까지 발생했던 모든 결과들을 조회한다

## 콘솔 구현

- [x] 기존 코드 출력 방식 변경
- [x] 기존 코드를 재활용하여 중복을 줄이는 방향으로 리팩토링한다

## ✔️ 기능 요구사항

- [x] 자동차 경주 코드 가져오기

### 웹 구현

- [x] 자동차 경주 웹 요청 구현
- [x] 자동차 경주 웹 응답 구현

### DB 연동

- [x] DB 연동하기
- [x] `H2 데이터베이스` 연동하기
- [x] 자동차 경주 게임 플레이 이력 저장
- [x] `DB 테이블 스키마` 구현

### DAO

- [x] Game 정보를 관리하는 DAO 기능 구현
- [x] Winner 정보를 관리하는 DAO 기능 구현
- [x] Result 정보를 관리하는 DAO 기능 구현
- [x] Car 정보를 관리하는 DAO 기능 구현
- [x] Car 정보를 전달하는 CarEntity 기능 구현

## API

![](./docs/api.png)

[링크](https://documenter.getpostman.com/view/19879275/2s93XvVQA1)에서도 확인하실 수 있습니다.

## DB 테이블

![](./docs/table.png)

# 모듈간 의존성

```mermaid
graph TD
web --> domain
console --> domain
domain-h2 --> domain
web --> domain-h2
console --> domain-h2
```
7 changes: 7 additions & 0 deletions application/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation project(":domain")
}

bootJar { enabled = false }
jar { enabled = true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.repository;

import java.util.List;
import racingcar.domain.RacingGame;

public interface RacingGameRepository {

RacingGame save(final RacingGame racingGame);

List<RacingGame> findAll();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package racingcar.repository;

import racingcar.domain.Winners;

public interface WinnerRepository {

void save(Winners winners);
}
34 changes: 34 additions & 0 deletions application/src/main/java/racingcar/service/RaceAddService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package racingcar.service;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import racingcar.domain.NumberPicker;
import racingcar.domain.RacingGame;
import racingcar.repository.RacingGameRepository;
import racingcar.repository.WinnerRepository;

@Service
public class RaceAddService {

private final NumberPicker numberPicker;
private final RacingGameRepository racingGameRepository;
private final WinnerRepository winnerRepository;

public RaceAddService(final NumberPicker numberPicker, final RacingGameRepository racingGameRepository,
final WinnerRepository winnerRepository) {
this.numberPicker = numberPicker;
this.racingGameRepository = racingGameRepository;
this.winnerRepository = winnerRepository;
}

@Transactional
public RacingGame addRace(final List<String> carsName, final int count) {
final RacingGame racingGame = new RacingGame(carsName, count);
racingGame.race(numberPicker);

final RacingGame savedRacingGame = racingGameRepository.save(racingGame);
winnerRepository.save(savedRacingGame.findWinner());
return savedRacingGame;
}
}
27 changes: 27 additions & 0 deletions application/src/main/java/racingcar/service/RaceFindService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.service;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import racingcar.domain.RacingGame;
import racingcar.domain.Winners;
import racingcar.repository.RacingGameRepository;

@Service
public class RaceFindService {

private final RacingGameRepository racingGameRepository;

public RaceFindService(final RacingGameRepository racingGameRepository) {
this.racingGameRepository = racingGameRepository;
}

@Transactional(readOnly = true)
public List<RacingGame> findAllRace() {
return racingGameRepository.findAll();
}

public Winners findWinners(final RacingGame racingGame) {
return racingGame.findWinner();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package racingcar.service;

import racingcar.domain.Winners;
import racingcar.repository.WinnerRepository;

public class DummyWinnerRepository implements WinnerRepository {

@Override
public void save(final Winners winners) {
// do nothing
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package racingcar.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
import racingcar.domain.Car;
import racingcar.domain.RacingGame;

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(ReplaceUnderscores.class)
class RaceAddServiceTest {

private final List<String> carsName = List.of("브리", "토미", "브라운");
private final int count = 10;
private RaceAddService raceAddService;

@BeforeEach
void setUp() {
raceAddService = new RaceAddService(new StubNumberPicker(10),
new StubRacingGameRepository(), new DummyWinnerRepository());
}

@Test
void 레이스_진행() {
final RacingGame racingGame = raceAddService.addRace(carsName, count);
final List<Car> winners = racingGame.findWinner().getCars();
assertAll(
() -> assertThat(winners).hasSize(3),
() -> assertThat(winners.get(0).getCarName()).isEqualTo("브리"),
() -> assertThat(winners.get(0).getPosition()).isEqualTo(10),
() -> assertThat(winners.get(1).getCarName()).isEqualTo("토미"),
() -> assertThat(winners.get(1).getPosition()).isEqualTo(10),
() -> assertThat(winners.get(2).getCarName()).isEqualTo("브라운"),
() -> assertThat(winners.get(2).getPosition()).isEqualTo(10)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package racingcar.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
import racingcar.domain.RacingGame;

@SuppressWarnings({"NonAsciiCharacters"})
@DisplayNameGeneration(ReplaceUnderscores.class)
class RaceFindServiceTest {

private RaceFindService raceFindService;

@BeforeEach
void setUp() {
final StubRacingGameRepository racingGameRepository = new StubRacingGameRepository();
racingGameRepository.setGameIdToRacingGame(Map.of(
1, new RacingGame(List.of("브리", "토미", "브라운"), 10)
));
raceFindService = new RaceFindService(racingGameRepository);
}

@Test
void 레이스_조회_테스트() {
final List<RacingGame> allRace = raceFindService.findAllRace();

assertAll(
() -> assertThat(allRace).hasSize(1),
() -> assertThat(allRace.get(0).findWinner().getCars()).hasSize(3)
);
}
}
17 changes: 17 additions & 0 deletions application/src/test/java/racingcar/service/StubNumberPicker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package racingcar.service;

import racingcar.domain.NumberPicker;

public class StubNumberPicker implements NumberPicker {

private final int result;

public StubNumberPicker(final int result) {
this.result = result;
}

@Override
public int pickNumber() {
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package racingcar.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import racingcar.domain.Car;
import racingcar.domain.RacingGame;
import racingcar.repository.RacingGameRepository;

public class StubRacingGameRepository implements RacingGameRepository {

private final Map<Integer, RacingGame> gameIdToRacingGame = new HashMap<>();
private int maxCarId = 0;
private int maxGameId = 0;

@Override
public RacingGame save(final RacingGame racingGame) {
final List<Car> carWithId = racingGame.getCars()
.stream()
.map(car -> new Car(car.getCarName(), car.getPosition(), ++maxCarId))
.collect(Collectors.toList());
final RacingGame racingGameWithId = new RacingGame(
++maxGameId,
carWithId,
racingGame.getCount().getTargetCount());
gameIdToRacingGame.put(maxGameId, racingGameWithId);
return racingGameWithId;
}

public void setGameIdToRacingGame(final Map<Integer, RacingGame> gameIdToRacingGame) {
this.gameIdToRacingGame.clear();
this.gameIdToRacingGame.putAll(gameIdToRacingGame);
}

@Override
public List<RacingGame> findAll() {
return new ArrayList<>(gameIdToRacingGame.values());
}
}
33 changes: 22 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

sourceCompatibility = '11'

repositories {
mavenCentral()
bootJar {
enabled = false
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
allprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
Comment on lines +15 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버전 명시안하면 현재 루트 버전과 달라질수도 있지 않나요? (진짜 궁금)

group 'racingcar'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게하면 콘솔에도 웹 의존성이 들어가지 않나요? (진짜 궁금)

testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
useJUnitPlatform()
tasks.named('test') {
useJUnitPlatform()
}
}
5 changes: 5 additions & 0 deletions console/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
implementation project(":application")
implementation project(":domain")
implementation project(":domain-h2")
}
46 changes: 46 additions & 0 deletions console/src/main/java/racingcar/ConsoleRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package racingcar;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import racingcar.domain.Car;
import racingcar.domain.RacingGame;
import racingcar.service.RaceAddService;
import racingcar.service.RaceFindService;
import racingcar.view.InputView;
import racingcar.view.OutputView;

@Configuration
public class ConsoleRunner {

private final RaceAddService raceAddService;
private final RaceFindService raceFindService;

public ConsoleRunner(final RaceAddService raceAddService, final RaceFindService raceFindService) {
this.raceAddService = raceAddService;
this.raceFindService = raceFindService;
}

@Bean
public CommandLineRunner commandLineRunner() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 클래스는 태어나서 처음보네요 뭐죠?
제가 찾아볼 수는 있지만 눈우의 메타인지를 위해 설명해주세요

return args -> {
final RacingGame racingGame = raceAddService.addRace(InputView.inputCarName(), InputView.inputTryCount());
final List<String> winnerNames = raceFindService.findWinners(racingGame)
.getCars()
.stream()
.map(Car::getCarName)
.collect(Collectors.toList());
OutputView.printWinner(winnerNames);
OutputView.printCarsStatus(getRacingGameStatus(racingGame));
};
}

private Map<String, Integer> getRacingGameStatus(final RacingGame racingGame) {
return racingGame.getCars()
.stream()
.collect(Collectors.toMap(Car::getCarName, Car::getPosition));
}
}
Loading