- Published on
우아한테크코스 5기 백엔드 프리코스 2주차 후기 - 숫자야구
지금까지 나의 커밋은 feat, fix, docs가 대부분이었다. 이번 2주차에는 내가 써보지 못한 커밋 메시지를 써보게 되었다. 바로 refactor, test, style! 2주차 미션을 통해 다음과 같은 경험을 새로 해보고, 배워가게 되었다.
- 자바 코드 컨벤션을 준수한 코드 작성
- 테스트 코드 작성
- 코드 리팩토링
- 스스로의 고민을 담은 클래스 설계
특히 많이 부딪히고, 기억에 남았던 부분에 대해 기록을 남겨보고자 한다.
클래스 설계
클래스 설계 과정
나는 지난 1주차 미션에서는 별도의 클래스 분리를 하지 않았다. 그러나 이번 2주차 미션에서는 클래스 설계와 분리의 필요성을 느꼈다. 단순한 게임 로직 구현뿐 아니라 입력, 출력, 예외처리와 같이 많은 기능이 요구되었으며 이들을 하나의 클래스에서 모두 처리하기에는 그 역할이 광범위했기 때문이다. 이는 객체지향 설계 원칙 중 객체는 오직 하나의 책임만을 가져야 한다는 단일 책임 원칙에도 위배된다.
클래스 분리가 필요하다고 느낀 나는 원래 BaseballGame이라는 클래스에 모든 기능을 구현하다가, 입력과 입력에 대한 예외 처리 등 입력과 관련된 처리를 담당하는 Input 클래스를 따로 만들어 분리하였다. 마찬가지로 Output 클래스도 분리하고 싶었으나 일부 기능이 BaseballGame과 겹쳐 애매하다 느껴 패스한 것이 아쉽다.
중간에 static에 대해 한 번 고민해보는 경험도 했다. 새로운 클래스를 생성하는 과정에서 기존 클래스의 메소드를 옮기고 그 과정에서 발생한 non-static method cannot be referenced from a static context 이슈 해결을 위해 우선 인텔리제이의 추천대로 메소드와 멤버 변수에 static을 홀린듯이 때려박다가 '잠시만, 제정신인가?' 싶어서 바로 중단 ✋ 나의 의도는 게임을 시작할 때마다 BaseballGame 인스턴스가 생성되는 것이었고, BaseballGame의 메소드들은 각 인스턴스의 멤버변수를 활용하여야 한다. 또, 이 인스턴스 변수들은 모든 인스턴스가 공유하는 것이 아니라 각 인스턴스마다 고유하며 서로 영향을 미치지 않는다. 즉, 내 의도와 맞지 않는 static을 사용할 이유가 전혀 없다. 다시 Ctrl+z를 반복해 static을 모두 지우고, 대신 new()로 객체를 생성하는 구문과 this 키워드를 추가했다. 생각해보면 아직 객체가 만들어지지 않았는데 바로 사용할 수 없는 게 당연하다. 기술적 고민이라기보다는 나의 미숙함+조급함에서 나온 어이 없는 실수지만 당장의 에러 해결에 급급하기보단 어떤 설계로 무얼 하려는건지 스스로 집중하자는 교훈을 얻었다.
나의 클래스 설계
이런 고민들을 거쳐 아래와 같이 클래스를 설계했다.
- BaseballGame : 게임 시작, 재시작, 종료, 타겟 넘버 생성 등 게임 진행에 필요한 기능과 로직
- Input : 사용자로부터 입력을 받는 기능과 입력 유효 검사 및 예외 처리
원래는 단일 클래스로 구현하다가 도중에 Input 클래스가 분리되어 나오긴 했지만, 책임별로 클래스가 명확히 나누어지지는 않았다.
첫째로, 상술한 것처럼 Output 클래스가 없는 것이 아쉽다. BaseballGame에 구현된 기능 중 안내 메시지를 함께 출력하는 기능이 다수 있어 Output 클래스로 따로 분리하기가 애매했고, 또 메소드를 나누자니 문자열 하나 출력하는데 메소드를 분리하는 것이 맞나? 라는 생각도 있었다.
둘째로, main에서 BaseballGame 객체를 새로 생성하는 로직을 do...while문으로 바로 작성했는데, 이를 관리하는 GameManager 등의 클래스가 있으면 좋을 듯하다.
코드 컨벤션
공백도 코딩 컨벤션이다! 1주차 공통 피드백 중 가장 기억에 남았던 문장이다. 가독성이 좋은 코드는 단순히 주관적인 판단 && 개인의 센스에만 의존하는 것인줄 알았는데 공백과 들여쓰기 등에 대한 코드 컨벤션 또한 존재하는 것이 신기하고 인상깊었다. 최대한 자바 코딩 컨벤션을 준수하고자 노력하며 코드를 작성했다. 네이버 캠퍼스 핵데이 Java 코딩 컨벤션이 많은 도움이 되었다.
테스트 코드 & TDD
이번 2주차 미션을 진행하며 생전 처음으로 테스트 코드라 하는 것을 작성해보았다! 테스트 코드를 작성하니 테스트 자체도 매우 간편해지고, 또 테스트뿐만 아니라 개발 생산성도 좋아진다고 느꼈다. 어떤 기능과 예외처리가 필요한지 야무지게 알 수 있다.

실제로 입력 예외 케이스를 먼저 작성하고나서 해당 입력에 대한 예외처리가 빠진 것을 확인하여 테스트 코드 작성 후 새로운 기능을 추가하기도 했다! 첫 테스트 코드 경험이지만 왜 테스트 코드가 필요한지 직접 체감할 수 있었고, 또 이렇게 테스트 코드가 주는 개발 생산성을 체감하며 테스트 기반 개발(TDD) 방식에 대한 관심도 커졌다. 나중에 TDD 기반 개발을 해보고 싶다.
# 더 공부하고 싶은 것
- 디자인 패턴
문제 해결을 위해 어떤 최적의 설계를 할 것인가? 디자인 패턴은 좋은 힌트를 제시한다. 직접 클래스 설계와 분리를 해보며, 여러 디자인 패턴 중 스스로 적절해보이는 모델을 찾아 적용해보는 것도 좋은 공부가 될 것이라는 생각이 들었다.
- JUnit5를 사용한 테스트 코드 작성
아직 많이 미숙하여, 더 많은 공부가 필요한 부분이다. 개발 전에 테스트 코드를 작성하는 TDD를 적용해봐도 큰 도움이 될 것 같다.
막막했던 프리코스 기간도 어느덧 절반이 지나갔다. 프리코스에서 해보는 것들 대부분이 나에겐 낯선 것이었고 (우선 언어부터.. 그리고 기능 목록, 기능 단위 커밋, 클린코드, 컨벤션, 테스트 코드, 리팩토링까지!) 매주 새로운 도전을 만났다. 그 도전에 모든 것을 쏟아부으며 임했는지 스스로 반성한다. 힘든 일도 있었고, 그 과정에서 좌절하기도 했지만 여기서 멈추지 말고 더 분발해야 함을 늘 명심해야 한다. 3주차 후기를 쓰면서는 더 더 더 성장하고 더 더 열심히 한 내가 되어 있었으면 좋겠다. 3주차 미션이 기대된다!