Web/Java

[우테코 프리코스] 2주차: 자동차 경주 게임

🚀 기능 요구사항

초간단 자동차 경주 게임을 구현한다.

  • 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
  • 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
  • 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
  • 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
  • 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다.
  • 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
  • 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
  • 아래의 프로그래밍 실행 결과 예시와 동일하게 입력과 출력이 이루어져야 한다.

 

 


이번 과제는 3가지를 중점으로 진행하려고 합니다.

 

  1. 피드백을 최대한 반영 (메소드명 축약금지 - 길어도 된다, README.md 쓰기)
  2. 추가된 요구사항 (메소드 15줄 이내, 한가지 기능만 수행) 지키기
  3. 개발(구현) 순서 정하기

 

README.md 작성

피드백에 README.md에 이 프로젝트가 어떤 프로젝트인지, 어떤 기능을 담고있는지 등을 기술하라고 하셨습니다.

 

이번엔 지난번 리드미에 적지 않은 기술스택, 프로젝트 실행방법, 입출력방법 등을 추가했습니다.

리드미 보러가기

 

 

메소드명 축약금지, 아무리 길어도 상관없다

메소드 이름이 길어도 상관없다는 것이 충격적이었습니다.

그래서 클린코드 책을 구매해 메소드부분을 정독했습니다.

 

  • 작게 만들어라
  • 한가지만 해라
  • 서술적인 이름을 사용하라

 

메소드이름이 자세하고 길수록 오히려 영어로 된 글을 읽는 느낌이었습니다.

그리고 메소드의 기능이 명확해 질수록 이름이 길어졌고 여러개로 쪼개졌습니다.

 

 

 

 

구현 순서를 명확히 해서 시작할때 당황하지 말자

이번엔 TDD로 구현해봐야지 생각했지만 제 개발순서가 아직 정해지지 않고 뒤죽박죽이라 TDD가 잘 되지 않았습니다.

테스트 코드를 먼저 작성하면 클래스나 메소드를 작성할때 마다 테스트 코드가 바뀌었습니다.

 

그래서 이번엔 TDD를 포기하고 제 개발패턴을 정형화 시키고 싶었습니다.

 

먼저 MVC 패턴에 대해서 다시한번 정리했습니다.

  • M (model) : domain, repositpory, service
    • Controller, View가 어떻게 생겼는지 몰라야함
    • domain, repository, service 역할 다시 생각하기
      • domain : 객체 기본정보, 기본메서드
      • repository : 객체 데이터 저장, 꺼내기
      • service : 해당 객체의 서비스 로직
  • V (view)
    • Model, Controller를 몰라야함
    • 가공된 데이터를 받아 화면에 뿌려주기만 하기
    • static method로 구성하기
  • C (Controller)
    • View에서 데이터를 입력받고 Model을 통해 데이터를 가공시키기
    • 가공된 데이터를 다시 View에 뿌리기
    • user input validation check

 

 

그 다음엔 개발을 기능 순서로 진행했습니다.

기능단위커밋에서는 순서가 중요했습니다.

정말 이상적인 순서는 기능에 어떤 서비스 로직이 들어갈지 작성되어있고,  도메인과 서비스로직부터 개발하는 것이었습니다.

하지만 기능만 보고 클래스 설계와 서비스로직 설계하는 것이 생각보다 어려웠습니다.

view부터 제작하고 사용자 입력을 받은 후에 컨트롤러로 어떤 로직을 부르면 될지 생각하는게 더 편했습니다.

 

그래서 이번과제까지는 view를 먼저 제작하고 도메인을 나중에 작성하면서 도메인에 기본적으로 어떠한 요소들이 개발되는지 파악하고 적응했습니다.

 

지금까지는 도메인까지는 알고있었고 레포지토리와 서비스로직이 헷갈렸지만 이번에 제대로 한 사이클을 경험해서 다음과제부턴 기능만 보고 Model부분을 먼저 제작이 가능할 것 같습니다.

애초에 기능목록을 작성할 때 이를 염두에 두고 작성하면 더 수월할 것 같습니다.

 

최종 시험에서는 문제를 보자마자 내게 익숙한 구현순서로 빠르고 정확하게 구현하는 것이 중요할 것 같습니다.

그래서 다음 과제는 하나의 과제를 여러번 구현해보려고 합니다.

하나의 과제를 여러번 구현해보며 기능목록순서대로, MVC패턴에 맞게, 메소드당 최소한의 기능으로 구현해보는 연습을 해야합니다.

 

 

 

 

 

 

힘들었던 점

이번 과제의 생각치도 못했던 복병은 우아한 테크코스 저장소의 추가된 커밋이었습니다.

내 저장소로 fork하고나서 원래의 저장소에 커밋이 추가되면 PR이 되지않았습니다.

 

일단 이 문제는 원래 저장소의 히스토리와 제 저 브랜치의 히스토리가 달라서 완전히 다른 저장소로 인식하기 때문에 PR이 되지 않는 것이었습니다.

 

refactor와 feat 사이에 fix가 추가되어야 했습니다.

 

그래서 4시간동안 내 저장소, 내 브랜치의 커밋히스토리에 원래 저장소에 추가된 커밋을 추가하는 방법을 찾았습니다.

 

몇시간의 시행착오 끝에 제가 해결한 방법을 간단히 기록해 놓습니다.

 

새로운 브랜치에 원래 커밋을 옮겨오는 방법을 사용했습니다.

  1. 새로운 커밋이 추가되기 이전 커밋으로 checkout (feat: setup racingcar ...)
  2. 새로운 브랜치를 생성하고 checkout
  3. (remote)원격저장소를 우테코 저장소로 연결
  4. fetch upstream 으로 추가된 커밋 가져오기
  5. 그 위에서 내 브랜치에서 커밋했던 내용들을 하나씩 cherry-pick
  6. (remote)원격저장소를 다시 내 저장소로 연결
  7. push

 

새로운 브랜치에 커밋을 옮겨온 이유

cherry-pick을 하면 지금 가리키고 있는 헤드 위로 커밋이 쌓입니다. 이미 dongho 브랜치는 맨 위를 가리키고 있어서 그 위에서 cherry-pick을 하면 지금까지 작성했던 내용이 지워지고 cherry-pick한 내용으로 덮어써집니다.

 

rebase를 이용해서 해결하려고 여러번 시도했지만 저는 이미 제 브랜치의 헤드가 뒤를 가리키고 있었고 커밋의 양이 좀 됐기 때문에 rebase로는 해결이 안되는 것 같았습니다.

  1. 원래 저장소의 새로운 커밋을 fetch한 브랜치 만들기 (name: base)
  2. dongho branch로 rebase
  3. dongho branch에서 base branch를 merge
  4. push

로 해결하려고 시도했는데 실패했습니다.

 

rebase로 성공하신 분들께 한번 여쭤봐야 할 것 같습니다.

그런데 rebase로 해결하신 분들은 conflict가 떴다고 하니 여기선 제 방식으로 해결하는게 맞다고 생각이 들지만 그래도 rebase로 해결하는 방법도 너무 궁금하네요.

 

 

 

 

 

내가 작성한 2주차 과제 보러가기

 

 

 

 

 

 

3주차 과제진행 포부

 

2주차 과제는 더 수월할 것이라고 생각했지만 고전했습니다.

3주차 과제는 난이도도 더 어려워 질 것이기 때문에 마음 단단히 먹고 일주일간 과제에 올인하려고 합니다.

 

  • 기능목록을 작성할때 model부터 작성할 수 있도록 설계한다.
  • 처음부터 제대로 작성해서 refactor commit을 줄인다.
  • 여러번 재구현 한다.
  • 3주차 과제에 익숙해지면 다른 기수의 3주차 과제와 최종시험을 구현해본다.

 

 

 

 

 

 

 

 

'Web > Java' 카테고리의 다른 글

[우테코 프리코스] 최종시험 + 최종합격  (3) 2021.12.31
[우테코 프리코스] 3주차: 자판기  (2) 2021.12.11
[우테코 프리코스] 1주차: 숫자 야구 게임  (2) 2021.11.25
[Java] 람다식  (2) 2021.09.01
[Java] 제네릭  (1) 2021.08.30