매우 늦은 회고를 작성해보려고 한다.
3주차, 4주차 회고를 노션에 작성했지만 블로그에 옮기지를 못했다.
그래서 한 번에 작성해보려고 한다.
참여하신 분들 모두 고생하셨습니다.
3주차 과제 역시 구현 기능 사항을 리드미에 먼저 정리하였다.
요구사항과 문제를 분석한 뒤에 구현해야하는 사항들과 검증해야하는 사항에 대해 정리하였고, 테스트도 구현 기능과 검증 부분을 나눠 목록을 작성하였다.
기능을 구현하기 전에 필요한 상수들을 정리하였다. 그 이후에는 입력값에 대한 검증 코드를 작성하였으며, 코드를 작성하면서 필요한 상수들을 추가해나갔다.
뿐만 아니라 각 예외 상황에 맞게 메세지를 출력할 수 있도록 메세지들을 별도로 정리하여 작성하였다.
상수들과 예외 메세지는 enum
을 사용하여 구현하였다.
검증 코드를 작성한 후에는 테스트 코드를 작성하여 예외 처리가 잘 되고 있는지 확인하였다.
이후에는 각 기능을 구현하였으며, 기능 구현 이후에 도메인별로 분리하는게 좋을 것 같다고 느껴 구현한 코드를 리팩토링하였다. 도메인별로 분리한 후에는 테스트 코드를 작성하여 구현한 기능에 대한 테스트를 진행하였다.
기능을 구현하면서 초기에 작성한 구현 기능 사항이 너무 세분화 되어 있거나, 단위가 큰 경우 혹은 불필요한 경우가 있으면 문서를 수정하며 진행했으며, 테스트 코드를 작성할 때 변경이 필요하다고 느껴지는 부분이 있으면 수정해 나가며 진행하였다.
기능을 구현하거나, 코드 혹은 문서를 수정하는 경우에 커밋 컨벤션을 참고하여 깃허브에 커밋하였다.
첫번째로 어려웠던 점은 6개의 로또 번호를 리스트로 생성한 후 변수에 바로 할당하고 Collections.sort()
로 오름차순하려고 했더니 불변객체라서 불가능하다는 것을 확인했다.
이를 해결하기 위해 방법을 찾아보았고 2가지 정도 선택지를 얻을 수 있었다. 먼저 변수를 선언할 때 새로운 리스트를 생성해서 할당한 후 로또 번호 리스트를 할당하는 것과 stream
을 이용하여 오름차순 하는 방법이 있는 것을 알았다. 나는 후자의 방법을 선택하여 진행하였다.
두번째로 어려웠던 점은 IllegalArgumentException
를 발생시키고 에러 메세지를 출력하는 것이었다.
예외가 발생한 곳에서 메세지를 출력하였는데도 테스트 코드에 통과하지 못하는 문제가 있었다.
여러 시도 끝에 더 상위 단계에서 try-catch
문을 통해 예외를 잡고 메세지를 출력하니 해결할 수 있었다.
마지막으로 어려웠던 것은 테스트 코드 작성이다.
아직은 테스트 코드를 작성하는 것이 미숙하여 제대로 작성한 것인지 확신이 서지 않았다. 하지만 미흡한 테스트 코드일지라도 기능 구현을 한 코드를 개선하는데 도움이 된다고 느꼈다. 테스트 코드를 작성하기 위해 기존 코드를 수정하고 다듬어 나가는 과정에서 테스트 코드의 중요성을 알 수 있었고, 어렵지만 즐거웠던 것 같다.
그런데 어려웠던 점은 enum
의 사용방법에 대해 찾아보고 적용은 하였지만, 이번 과제와 같은 상황에서 enum
을 사용하는 것이 적절한지에 대한 고민에 빠졌다.
반복적으로 수정을 해야하는 문제인데 enum
을 사용해도 될지.. 제출하는 순간에도 확신이 서지 않았지만 그래도 enum
을 사용하기 위해 찾아보고 시도했다는 것에 의의를 두려고 한다.
이후 enum
을 적절하게 사용할 수 있도록 다시 공부해보고자 한다.
기능 구현을 모두 한 후에 테스트 코드를 작성하고자 미리 작성된 테스트 코드부터 읽어보았다.
바로 이해하기 조금 어려워서 테스트를 공부하고 다시 봐야겠다는 생각을 하게 되었다.
테스트를 공부했지만, 바로 적용하는 것이 어려워서 기존에 있던 테스트코드를 활용해 예외에 대한 테스트만 간단하게 작성하고 다른 테스트는 작성하지 못했다.
이후에 enum과 같이 테스트 코드를 작성하는 것에 대해 공부해보고자 한다.
4주차 과제는 요구사항이 많고 클래스별 제한 사항이 있어서 요구사항을 숙지하는 시간을 많이 투자하였다. 문제를 온전히 이해한 후에 요구사항들을 숙지한 뒤에 구현 기능 목록을 작성하였다.
구현 기능 목록은 기능 구현, 검증 구현, 테스트 구현으로 구분하여 작성하였다. 기능을 구현하기 전에 필요한 상수들을 정리하였고, 추가적으로 필요한 경우 기능을 구현하면서 추가해나갔다. 유사한 특징으로 그룹화 할 수 있는 상수들은 모두 enum
으로 처리하였다.
지난 미션들에서 enum
내부 필드를 계속 수정하며 문제를 해결하다보니 테스트 코드를 작성할 때 코드를 추가하고 수정해야하는 문제가 있었다. 그래서 enum
의 사용을 잘못하고 있는 것 같다고 느껴서 이번 과제를 진행할 때는 enum
의 값을 변경하지 않고 상수로 두고 활용하도록 하였다.
그 다음으로는 사용자의 입력값을 받는 메서드들을 구현하고, 입력값을 검증할 수 있도록 코드를 작성하였으며 검증에 실패한 경우 Exception
메세지를 통해 어떠한 문제가 있는지 확인할 수 있도록 하였다.
각 입력값에 공통되는 메서드들이 있고, 테스트할 때도 따로 검증 코드를 빼서 하는 것이 좋을 것 같다고 판단하여 Validator
클래스에 검증 메서드를 작성하고 사용자의 입력값을 받는 메서드들을 작성한 InputView
가 상속하도록 하였다.
지난 미션들과 다르게 예외가 발생하고 다시 입력을 받아야하는 요구사항이 있어서 많이 고민하였다.
처음에는 while문
을 사용해서 코드를 재 작성 해야할지 고민하였으나 그렇게 되면 모든 입력 값에 while문
을 추가하고 따로 처리해줘야하기 때문에 반복적이고 불필요한 코드가 증가하고 요구사항 중 하나인 ‘메서드의 길이가 10을 넘지 않아야한다’ 조건에 걸리기 때문에 오래 고민하게 되었다.
그러던 중 재귀함수가 떠올라서 try-catch문
으로 예외를 잡아서 메세지를 출력하고 다시 해당 메서드를 호출하는 방법을 사용하게 되었고, 성공적으로 예외를 처리할 수 있었다.
이후에는 각 기능을 구현하였으며, 구현 과정에서 최대한 클래스와 메서드를 분리하고자 하였다.
처음 설계할 때는 Map
을 이용하여 각 다리의 상태를 체크해야겠다고 생각하였으나, 코드를 작성하다보니 그렇게되면 여러 필드와 로직을 추가하게 되어 메서드의 사이즈가 커지고 하나의 메서드가 너무 많은 역할을 담당하게 된다고 생각하였다.
그래서 다리의 상태 체크나 한번의 게임에 대한 상태를 나타내는 Bridge
, Game
클래스를 따로 작성하여 관련된 메서드와 필드를 분리하는 작업을 하였다.
기능을 구현하면서 초기에 작성한 구현 기능 사항이 너무 세분화 되어 있거나, 단위가 큰 경우 혹은 불필요한 경우가 있으면 문서를 수정하며 진행하였다. 작성 및 변경 작업 후에는 커밋 컨벤션을 참고하여 깃허브에 커밋하였다.
이번 미션에서는 여러 종류의 요구사항이 있었다. 이 부분이 힘들긴 했지만 또 다른 즐거움이기도 했다. 마치 협업을 하고 있진 않지만 협업을 위해 규칙을 정해 놓고 코드를 작성하는 것 같아 새로운 기분이 들었다.
그리고 확실히 제약 사항이 추가되니 기능을 더 세세하게 나눠보게 되어 좋았던 것 같다.
클래스나 메서드의 내용을 변경하지 못하는 제약 사항도 너무 좋았다. 왜 그렇게 조건을 제시했는지 고민해보는 시간이 즐거웠고 다양한 방향으로 생각해볼 수 있어서 좋았던 것 같다. 전체 미션 중에 가장 시간을 많이 투자했고, 고민도 많이 했던 미션이었다.
그 동안 학습한 enum
의 활용, 메서드 기능 분리, 전역 변수와 지역 변수의 사용, 객체 분리 등을 충분히 고려하고 정리할 수 있던 시간이었다.