Seren dev's blog
article thumbnail

프리코스 2주차 미션을 진행한 과정, 느낀 점, 개선할 점을 작성한 회고록이다.

프리코스 2주차 미션은 "숫자야구게임" 미션으로, 숫자야구게임을 구현해야 한다.

1주차에 비해 여러가지 요구사항이 많아졌고, 메일로 1주차 공통 피드백도 전달받았는데 이번 미션뿐만 아니라 앞으로 코딩을 할 때도 많이 도움이 되는 피드백이었다.

전달받은 피드백들 중 나에게 많이 도움이 된 피드백을 아래에 적어두었다.

 

1주차 공통 피드백


1. 커밋 메시지를 의미 있게 작성한다

커밋 메시지에 해당 커밋에서 작업한 내용에 대한 이해가 가능하도록 작성한다.

 

2. 이름을 통해 의도를 드러낸다

나 자신, 다른 개발자와의 소통을 위해 가장 중요한 활동 중의 하나가 좋은 이름 짓기이다. 변수 이름, 함수(메서드) 이름, 클래스 이름을 짓는데 시간을 투자하라. 이름을 통해 변수의 역할, 함수의 역할, 클래스의 역할에 대한 의도를 드러내기 위해 노력하라. 연속된 숫자를 덧붙이거나(a1, a2, ..., aN), 불용어(Info, Data, a, an, the)를 추가하는 방식은 적절하지 못하다.

 

3. 축약하지 않는다

의도를 드러낼 수 있다면 이름이 길어져도 괜찮다.

누구나 실은 클래스, 메서드, 또는 변수의 이름을 줄이려는 유혹에 곧잘 빠지곤 한다. 그런 유혹을 뿌리쳐라. 축약은 혼란을 야기하며, 더 큰 문제를 숨기는 경향이 있다. 클래스와 메서드 이름을 한 두 단어로 유지하려고 노력하고 문맥을 중복하는 이름을 자제하자. 클래스 이름이 Order라면 shipOrder라고 메서드 이름을 지을 필요가 없다. 짧게 ship()이라고 하면 클라이언트에서는 order.ship()라고 호출하며, 간결한 호출의 표현이 된다.

- 객체 지향 생활 체조 원칙 5: 줄여쓰지 않는다 (축약 금지)

 

4. 공백 라인을 의미 있게 사용한다

공백 라인을 의미 있게 사용하는 것이 좋아 보이며, 문맥을 분리하는 부분에 사용하는 것이 좋다. 과도한 공백은 다른 개발자에게 의문을 줄 수 있다.

 

5. IDE의 코드 자동 정렬 기능을 활용한다

IDE의 코드 자동 정렬 기능을 사용하면 더 깔끔한 코드를 볼 수 있다.

  • IntelliJ IDEA: ⌥⌘L, Ctrl+Alt+L
  • Eclipse: ⇧⌘F, Ctrl+Shift+F

6. 배열 대신 Java Collection을 사용한다

Java Collection 자료구조(List, Set, Map 등)를 사용하면 데이터를 조작할 때 다양한 API를 사용할 수 있다.

 

프리코스 2주차 숫자야구게임 미션 Github 링크

나의 Github 링크

🚀 기능 요구 사항

기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다.

  • 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.
    • 예) 상대방(컴퓨터)의 수가 425일 때
      • 123을 제시한 경우 : 1스트라이크
      • 456을 제시한 경우 : 1볼 1스트라이크
      • 789를 제시한 경우 : 낫싱
  • 위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.
  • 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.
  • 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

🎯 프로그래밍 요구 사항

  • JDK 11 버전에서 실행 가능해야 한다. JDK 11에서 정상적으로 동작하지 않을 경우 0점 처리한다.
  • 프로그램 실행의 시작점은 Application의 main()이다.
  • build.gradle 파일을 변경할 수 없고, 외부 라이브러리를 사용하지 않는다.
  • Java 코드 컨벤션 가이드를 준수하며 프로그래밍한다.
  • 프로그램 종료 시 System.exit()를 호출하지 않는다.
  • 프로그램 구현이 완료되면 ApplicationTest의 모든 테스트가 성공해야 한다. 테스트가 실패할 경우 0점 처리한다.
  • 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 이름을 수정하거나 이동하지 않는다.

추가된 요구 사항

  • indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
    • 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
    • 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
  • 3항 연산자를 쓰지 않는다.
  • 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
  • JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.
    • 테스트 도구 사용법이 익숙하지 않다면 test/java/study를 참고하여 학습한 후 테스트를 구현한다.

✏️ 과제 진행 요구 사항

  • 미션은 java-baseball 저장소를 Fork & Clone해 시작한다.
  • 기능을 구현하기 전 docs/README.md에 구현할 기능 목록을 정리해 추가한다.
  • Git의 커밋 단위는 앞 단계에서 docs/README.md에 정리한 기능 목록 단위로 추가한다.
  • 과제 진행 및 제출 방법은 프리코스 과제 제출 문서를 참고한다.

 


2주차 미션 목표 : 함수를 분리 & 함수별로 테스트 작성

2주 차 미션에서는 1주 차에서 학습한 것에 더해 함수를 분리하고, 각 함수별로 테스트를 작성하는 것에 익숙해지는 것을 목표로 하고 있다.

📋 구현 기능 목록

  • 랜덤 숫자 생성
  • 사용자 입력 및 검증
  • 입력에 대한 점수 계산
  • 게임 결과 출력
  • 게임 종료 시 입력과 조건 검사

기능을 구현하기 전에 먼저 docs/README.md 파일에 기능 목록을 작성하였다. 1주차와 마찬가지로 한꺼번에 커밋하지 않고, 구현한 기능별로 메시지와 같이 커밋 메시지를 보내는 방식으로 진행했다. 또한 커밋 메시지 컨벤션 가이드를 참고하여 아래와 같이 커밋 메시지를 작성했다.

 

 

이 때까지는 아직 클래스를 분리하지 않고 하나의 Game 클래스에 모든 로직을 작성했다;;

 

기능 요구 사항에서 "사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다."고 나와있으므로 예외사항인 경우를 처리하는 사용자 입력 검증 메서드를 작성했다.

 

예외사항인 경우

  • 숫자 이외의 문자를 입력한 경우
  • 숫자를 3개보다 많거나 적게 입력한 경우
  • 중복되는 숫자를 입력한 경우
  • 게임이 끝났을 때, 숫자 이외의 문자를 입력한 경우
  • 게임이 끝났을 때, 1과 2 이외의 숫자를 입력한 경우

validateUserInput() 메서드와 validateUserExitInput() 메서드를 작성하여 사용자 입력 시 예외 사항인 경우 IllegalArgumentException을 발생하도록 하였다.

 

 

2주차 소감


개선할 점

이번 미션에서 클래스를 어떻게 분리할지 감이 오질 않아 Game 클래스 내에 모든 로직을 작성했는데, 클래스를 분리하는 법에 대해서 더 공부하여 다음 미션에는 MVC 패턴을 활용하여 클래스를 분리하는 연습을 해야겠다.

 

또한 이번 미션에서도 스트림을 전혀 사용하지 않았는데, 앞으로의 미션에서는 스트림을 적극적으로 사용하도록 노력하여 스트림에 익숙해져야겠다고 생각했다.

 

각 함수별로 테스트 코드를 작성할 때, 테스트 코드를 작성하기 위해 일부러 함수의 접근제한자를 모두 public으로 작성하였다. 하지만 스트라이크, 볼의 개수를 계산하는  calculateScore() 메서드와 게임 결과를 출력하는 printResult() 메서드는 Game 클래스 내의 private 변수를 사용하기 때문에 테스트 코드를 작성할 수 없었는데, 이런 경우에는 어떻게 테스트 코드를 작성하는지 잘 알지 못했다. 아마 클래스 분리를 하지 않고 Game 클래스 내에 모든 로직을 다 작성했기 때문에 모든 함수의 접근제한자를 public으로 작성해야지 테스트 코드 작성이 가능했던 것 같다.

 

미션 기간이 끝난 후 커뮤니티에서 private 접근제한자 메서드 테스트와 관련된 질의응답을 확인할 수 있었는데, 찾아본 바로는 private 메서드는 테스트 하지 않는 것을 지향하고, private 메서드를 포함하는 메서드의 테스트를 통해 테스트하라고 한다.

느낀 점

2주차 미션에서는 요구사항을 지키는 것과 함수를 분리하고, 각 함수별로 테스트를 작성하는 것에 익숙해지는 것에 집중했다.
이를 위해 하나의 메서드는 한 가지의 일만 담당하도록 메서드를 분리했다. 추가된 요구사항 중 "indent depth가 3이 넘지 않도록 구현한다"고 나와있는데, depth를 줄이는 좋은 방법은 메서드를 분리하는 것이므로, 메서드를 최대한 작게 만들어 위 요구사항을 지키고, 한 가지의 역할만 담당하도록 메서드를 작성했다.

 

또한 이번 미션에서는 테스트 도구로 JUnit5와 AssertJ를 이용하라고 나와있는데, 이전에 스프링을 학습하면서 인터넷 강의를 들을 때 JUnit5와 AssertJ를 사용하여 테스트 코드를 작성한 경험이 있기 때문에 사용 방법에 대해 간략히 알고 있었다. 그리고 test/java/study의 StringTest 코드를 참고하여 각 함수별로 테스트 코드를 작성했다.

 

[프리코스 1주 차] 웹 백엔드 피드백을 보면 커밋 메시지를 의미 있게 작성해야 한다고 나와있는데, 저번 미션에서는 커밋 메시지를 너무 작은 단위로 많이 작성한 것 같아서 이번 미션은 README.md에 정리한 기능 목록 단위로 커밋하도록 노력하였고, 읽는 사람을 생각하여 커밋 메시지를 의미 있게 작성하도록 노력했다.

또한 공백을 과도하게 사용하지 않고 문맥을 분리하는 부분에 사용하도록 노력했다.

 

피드백을 받고 미션을 진행하면서 많은 것을 배울 수 있었고, 프리코스를 통해 배운 것을 바탕으로 이번 프리코스 뿐만 아니라 앞으로 개발할 때도 객체지향과 클린코드 원칙을 잘 지키며 코딩할 수 있을 것 같다.

앞으로의 미션에서는 개선할 점을 적극적으로 반영하여 부족한 부분을 보완하고 더 많은 것을 공부해 나가고 싶다.

 

Reference

 

 

728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!