-
[우아한테크코스-프리코스] 1주차 숫자야구 회고를 해보자 ⚾️⭐️ 우아한테크코스 2023. 10. 26. 14:15
우아한테크코스 - 프리코스에 참여하고 첫 주의 미션으로 ‘숫자야구’를 구현했어야 했다.
🔗 나의 Pull Request Link
⚾ 숫자야구
🎯 요구사항
- [x] 1 ~ 9 사이의 서로 다른 수로 이루어진 3자리 수를 맞추기
- [x] 같은 수가 같은 자리인 경우 스트라이크, 다른 자리인 경우 볼
- [x] 컴퓨터가 1 ~ 9 까지의 서로 다른 임의의 수 3개를 선택
- [x] 게임 플레이어는 서로 다른 3개의 숫자를 입력하고 컴퓨터는 입력한 숫자에 대한 결과 출력
🤔 고민
1️⃣ 숫자야구에 필요한 상수들을 어떻게 관리할까?
숫자야구에서 필요한 상수들이 여러개 있었다.
- 몇 자리 수인지
- 게임 재시작 입력 값
- 게임 종료 입력 값
처음 생각한 것은 static final 변수로 선언해 사용하는 곳에서 사용하도록 했다.
private static final int DIGIT = 3; private static final String RESTART = "1"; private static final String EXIT = "2";
📖 static final
- 인스턴스가 만들어질 때마다 새로운 메모리에 초기화하지 않고, 하나의 메모리 공간만을 사용할 수 있다.
상수 값들이 다 떨어져 있다보니 변경사항이 발생했을 때 해당 상수값이 선언된 곳을 찾아 수정하는 과정이 불편하지 않을까? 라는 생각을 하게 되었다.
❗한 곳에서 상수들을 관리하면 좋지 않을까? 라는 생각을 해 열거형 클래스를 통해 처리하기로 했다.
public enum BaseBallGameConfig { BASEBALL_NUMBER_SIZE(3), BASEBALL_MIN_NUMBER(1), BASEBALL_MAX_NUMBER(9), BASEBALL_GAME_RESTART(1), BASEBALL_GAME_EXIT(2); ... }
이를 통해 변경사항이 생기면 해당 클래스에서 값만 바꾸게 되면 되었다.
- 유지보수가 더 쉬워지지 않았나?
2️⃣ 정규식을 통해서 입력된 숫자에 대한 검증❓
처음에는 사용자가 입력한 문자열에 대해서 정규식을 사용해서 아래의 조건을 검증하면 매우 편할 것이라고 생각했다.
- 입력된 수가 서로 다른 3개의 숫자
- 입력된 수의 범위가 1 ~ 9 사이
private boolean isValidatedInputString(String inputString) { String regex = String.format("^(?!.*(.).*\\\\1)[0-9]{%d}$", DIGIT); return inputString.matches(regex); }
이렇게 정규식을 통해 입력된 문자열에 대해 바로 검증하도록 했었다.
⚠️ 하지만, 정규식을 사용했을 경우 어떤 입력이 들어와 예외를 발생시켰을 때, 어떤 부분에서 검증이 실패했는지 정확하게 알 수 없었다.
- 입력된 수가 4자리인지 입력된 수의 범위를 넘어선 수가 입력되었는지 알 수 없음
❗저는 커스텀 예외를 만들어 어떤 부분에서 예외가 발생했는지 처리를 해주기 위해서 정규식보다 따로 검증하는 메서드를 나누어 사용하기로 선택했다.
메서드로 검증을 하는 경우 여러 중복 코드가 발생할 수 있는 문제가 있지만 많은 검증을 하지 않는다고 생각하여 이정도 중복은 괜찮을 것이라고 생각했다.
... private void validateSize(int[] numbers) { if(numbers.length != BASEBALL_NUMBER_SIZE.getValue()) throw new BaseBallGameException(INVALID_LENGTH); } private void validateWithinRange(int[] numbers) { for(int number : numbers) { if(number < BASEBALL_MIN_NUMBER.getValue() || number > BASEBALL_MAX_NUMBER.getValue()) throw new BaseBallGameException(OUT_OF_RANGE); } } private void validateDuplicate(int[] numbers) { Set<Integer> set = new HashSet<>(); for(int num : numbers) set.add(num); if(set.size() != BASEBALL_NUMBER_SIZE.getValue()) throw new BaseBallGameException(DUPLICATED_NUMBERS); } ...
이렇게 검증하는 메서드를 따로 두고 각각의 조건에 만족하지 않는 경우에 커스텀 예외를 통해 어떤 부분에서 예외가 발생했는지 명시적으로 보일 수 있도록 했다.
🤔 결론
선택한 내용이 정답은 아니겠지만 위 내용뿐만 아니라 다른 내용에 대해서도 고민하는 과정을 통해 더 많이 배울 수 있었던 시간이 되었던 것 같다.
아쉬운 점은 PR을 보내고 나니 코드에 부족한 부분이 더 보이는 것 같아 더 많은 best practice를 찾아봤으면 좋았을 것 같다.
⭐ 4Ls 회고
❤️ LIKED
- 이번 미션을 하면서 많은 동료분들과 함께 커뮤니케이션하면서 하다보니 좋은 자극들을 많이 받아 동기부여가 되었다.
- 동료분들이 고민하는 내용에 대해 알 수 있었고 그런 내용을 보며 좀 더 꼼꼼하게 코드를 작성해야겠다는 생각을 할 수 있었다.
- 테스트 코드를 작성해 숫자게임에 대한 로직을 수정했을 때 바로 짜놓은 테스트 코드를 통해 어떤 문제가 있는지 확인할 수 있었다.
📖 LEARNED
📍 JMH (Java Microbenchmark Harness)
- JVM 상에서 실행되는 코드의 성능을 측정하기 위한 벤치마크 도구
- 자바에 있는 Random 클래스에 대해 공부하면서 간단하게 성능을 비교해보려 찾아보다 공부하게 되었다
- 간단하게 성능 비교를 해볼 상황이 생긴다면 또 다시 사용해보고 싶다.
📍 일급 컬렉션
- 일급 컬렉션을 공부하고 이를 통해 일급컬렉션의 장점을 살려서 이번 미션을 해보려고 노력했다.
📍 Java 17
- 이번 미션을 하기 전까지 Java 11을 사용해왔었다. 이번 미션에서의 요구사항으로 Java 17이 있어 이번 기회에 Java 17에 대해 더 공부해볼 수 있었다.
- Java 11과 다르게 Java 17에서 추가된 기능에 대해서 이 미션에서 사용해볼 수 있는 것이 있다면 사용해보려고 했다.
- Record
- Switch Expression
🗑️ LACKED
- 테스트 코드를 작성하는 과정에서 실패 케이스를 더 생각할 수 있었을 것 같은데 그런 부분에서 아쉬웠다.
- commit 을 할 때 너무 사소한 내용에 대해서 commit을 한 것 같아 이런 부분에 대해서 공부하고 신경써서 기능별로 commit을 해야겠다는 생각을 하게 되었다.
➡️ LONGED FOR
- 이번에 부족하다고 느꼈던 부분, 배웠던 부분에 대해서 best practice를 더 찾아보고 적용해보고자 한다.
- 동료들이 고민하는 부분, 공유해준 부분에 대해서 함께 고민해보고 이에 대한 해결을 찾아가며 더 좋은 코드를 작성해보고 싶다.
'⭐️ 우아한테크코스' 카테고리의 다른 글
[우아한테크코스 - 프리코스] 4주차 로또 게임 회고 🤑 (1) 2023.12.07 [우아한테크코스 - 프리코스] 늦은 3주차 로또 게임 회고 😓 (0) 2023.11.28 [우아한테크코스-프리코스] 2주차 경주게임 회고를 해보자🏁 (0) 2023.11.02