[우테코 5기] 프리코스 2주차 회고록

 

 

숫자 야구 게임을 구현 미션인 2주차 과제는 다행이 1주차보다 구현에 어려움이 적었다.

 

자동으로 생성한 컴퓨터의 숫자값(1~9로 중복없이 3자리) && 내가 입력한 숫자값(1~9로 중복없이 3자리)
두 값을 비교하여, 아래와 같은 게임을 구현하는 것이다.

 

이번 주차에서는 특이하게도 컴퓨터의 자동으로 숫자를 입력받는 부분에 우아한형제들에서 제공하는 라이브러리를 사용하는 것이 규칙이었다.

우아한형제들에서 제공하는 라이브러리를 써볼 기회는 흔치 않으니 열심히 사용해주었다🙂

 

 

주요 개발 포인트

:: 예외 처리


1주차에선 예외가 발생하지 않도록 Test부분에서 값에 제한을 두어 제공해주었다. 하지만 이번엔 값을 제공받는 것이 아닌 내가 입력하는 것이기 때문에 얼마든지 예외가 발생할 수 있어 어떤 예외가 발생할 지 기능 구현 문서에 정리해두고 개발을 시작하였다. 또한 최대한 예외가 발생하지 않도록 구현하는 것도 신경 써주었다.

특히 예외를 검증할 때 LinkedHashSet을 유용하게 사용하였다.

 

:: LinkedHashSet

숫자에 중복이 발생하면 예외 처리가 되기 때문에 이 부분을 간단히 구현하기 위해 숫자를 LinkedHashSet에 입력 받았다.

Set은 중복이 있다면 하나를 제거해주는 특성을 가지고 있다. 때문에 중복을 감지하는 해당 예외 부분에서는 상당히 유용했다. 만약 [1, 2. 2] 를 입력 받았다면 Set에 저장되는 것은 [1, 2] 이기 때문에 Set에 입력 숫자를 담고 size로 체크해주기만 하면 되었다.

하지만 일반 HashSet은 순서가 없다는 특징이 있기 때문에 입력된 수의 순서를 파악할 수 없다.예를 들어서 만약 [123]을 입력했다고 할 때 이 문자열을 분리해서 Set에 [1], [2], [3] 순서로 add 한다면, 1,2,3이라는 숫자의 순서가 지켜지지 않아 제대로 값을 비교할 수 없게 된다.


때문에 순서까지 보장해주는 SetLinkedHashSet을 이용하여 구현하였다.

 

:: 숫자 비교


볼, 스트라이크를 체크하는 가장 중요한 부분이 숫자 비교이기 때문에 비중을 두어 개발하였다.

입력받은 문자열[123] 을 분리하여 LinkedHashSet에 저장된 값들은 Set의 특성상 get으로 가져올 수 없기 때문에 ArrayList로 반환하여 return받았고 그 값을 비교하여 결과를 도출했다.

비교할 숫자의 순서가 같아야 하기 때문에 반복문으로 총 공의 갯수(3) 만큼 반복하며 공을 하나하나 비교하였고 그 값을 통해 결과 값을 얻었다.

 

:: 테스트 코드 작성 / 메서드 기능 단위 구현


이번 주차에는 아래와 같이 테스트를 직접 구현해야 한다는 요구 사항이 추가되었다. 때문에 TDD 방법론을 채택하여 메서드 하나를 구현할 때마다 테스트를 구현해나가는 것을 디폴트 값으로 미션을 수행하였다.

본인은 메서드를 기능 단위로 구현하는 이유 중 하나는 테스트 코드 작성 간편화를 위함도 있다고 생각한다. 테스트 코드를 작성할 때 메서드 단위로 작성하게 되는데, 만약 메서드가 여러 기능이 짬뽕되어 있다면 테스트 코드가 상당히 길어질 가능성이 있다.

때문에 메서드를 기능 단위로 구현하는 것에 중점을 두어 테스트 코드를 짧고 간결하게 짤 수 있도록 노력하였다.

 

 

Clean Code

:: 매직 리터럴/매직 넘버 사용 지양


매직 리터럴은 1주차에서 신경썼던 매직 넘버와 유사한 개념으로 아래와 같이 언뜻 보아선 의미를 알기 힘든 상수가 아닌 문자열이다. String name = “csj”

이러한 매직 넘버, 매직 리터럴을 지양하기 위해 Constant 클래스를 구현하여 값을 담아 사용하였다.

 

:: 기능 단위로 메서드 구현


2주차 요구 사항에 “함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.” 가 추가되었다.

때문에 1주차 때보다 기능 단위로 메서드와 클래스를 분리하는 것에 많이 집중하였다.

 

:: 테스트 주도 개발 (TDD)


내가 구현한 기능 하나하나가 제대로 작동하는 지 확인하려면, 테스트 과정이 꼭 필요하다. 때문에 기능 별로 테스트를 구현해가며 개발하는 것에 집중하였다.

TDD 방식으로 기능 구현이 완료되면 더미 데이터를 사용해 기능 구현을 메서드 단위로 테스트 해보려고 하였지만, 테스트를 작성하는 습관을 들여놓지 않아 까먹고 그냥 작성해버린 코드들도 있었다. 때문에 아주 완벽한 TDD 방식은 아니었지만 그래도 최대한 테스트 주도 개발을 실천하기 위해 노력하였다.

 

 

부족했던 점

:: 네이밍


변수는 명사, 메서드는 동사로 네이밍 하는 것은 잘 지켜졌지만, 네이밍 자체가 생각보다 많은 시간을 잡아먹었다. 네이밍은 아직 많은 연습이 필요하다. 영어 공부와 프로그래밍 학습을 병행하여 보다 가독성 높은 네이밍을 할 수 있도록 노력해야겠다.

 

:: 테스트 코드 작성 미숙


위에서 말했다시피 테스트 코드를 작성하는 습관이 되어있지 않았기 때문에 테스트 코드 또한 작성하는 것이 미숙하였다. AssertJ와 Junit5를 기본적인 기능은 전부 테스트할 수 있을 정도로는 학습해두어야겠다고 생각하였다.

 

:: 클래스/패키지 분할 미숙


클래스와 패키지를 제대로 분할하는 것은 프로젝트가 어떤 동작을 하는 지 파악하는 데에 큰 역할을 한다고 생각한다. 하지만 생각보다 어려운 클래스와 패키지 분할에 꽤나 애먹었던 것 같다. 특히 네이밍 실력이 부족했기 때문에 패키지와 클래스를 더 분할하기 어려웠다. 앞으로도 계속해서 사용해야 할 중요한 부분이기 때문에 보완해야만 하는 부분이었다.