[우아한테크코스 7기] 프리코스 3주차 회고
https://github.com/chyo1/java-lotto-7/tree/chyo1
GitHub - chyo1/java-lotto-7
Contribute to chyo1/java-lotto-7 development by creating an account on GitHub.
github.com
들어가며
프로그래밍 요구 사항3의 내용들이 간단해 보이지만, 은근 어려웠다. 메서드 길이 15줄 제한이 빡빡해보이지 않았는데 여러 기능이 들어갔나 싶은 메서드들은 15줄이 넘어 있었다. 더 분리할 수 있을까 싶었는데 분리 후의 코드에서 '메서드가 한 가지 일만 하도록 구현한다'가 더 잘 나타났다. 각 주차의 요구사항이 적절하게 주어져서 더 좋은 코드를 구현하는 데에 도움이 되었던 것 같다.
README.md
공통피드백에서 README.md는 프로젝트 개요를 소개하는 문서이므로 상세하게 작성해야 한다는 내용을 보고 이번주차에는 해당 프로젝트의 기능 요구사항 및 구현해야 할 기능 목록, 예외 사항 등을 저번주차보다 자세하게 작성했다.
또한 README.md는 문서이고, 여기에 작성된 기능 단위로 커밋해야 했기에, 한 번 정한 기능은 변하지 않아야 한다고 생각했다. 하지만 메서드 단위가 아닌 기능 단위이므로, 변경 및 업데이트가 가능하다는 2주차 공통 피드백을 보고 완벽에 집착하지 않게 되었다. 그래도 기능만을 작성하여 구현할 기능 목록이 변경되는 일은 없게 하려고 노력했다.
기능 분리
저번주차까지 과제를 수행하며 구조 잡는 게 익숙해졌다고 생각했는데 이번주차에서 많은 시간을 썼다. 이번 주의 기능 분리가 가장 어려웠다. 대략적인 구조를 구상하고 코드를 구현했음에도 구조가 눈에 보이지 않아 막막했다. 그래서 메서드로 기능만 분리하며 코드를 짰다. 리팩토링이 어렵긴 하지만, 일단 실행은 되게 하자라는 생각으로 구현했다. 거기서부터 비슷한 기능끼리 묶어 클래스로 만들었더니 구조가 훨씬 깔끔해졌던 것 같다.
또한 주어진 클래스의 형태에 맞추는 것이 어려웠다.
현재 내 코드는 입력 -> 검증 -> 파싱 -> 객체 생성의 순서로 구현했는데, Car 객체 생성 시 validate를 수행하는 로직이 있어 해당 부분에서 검증을 한 번 더 시행했다. 하지만 입력을 받을 때, 에러인 경우 재입력을 받아야 한다는 요구사항과 겹쳐 이 부분의 검증을 뺄 수 없었다.
잘못된 입력과 로또 객체 생성 시의 잘못된 값에 대한 기준이 명확하지 않아 중복된 동작을 수행해서, 이 부분을 고치고 싶은데 내 기준 잘못된 입력은 로또 객체에서의 검증 내용을 포함하는 거라 두 군데 모두 검증을 시행했다. 객체의 책임은 아직 감이 잡히지 않는 것 같아서 더 공부가 필요할 것 같다.
Enum
이번주의 프로그래밍 요구사항 중 Enum 객체를 사용해야 한다는 조건이 특히 어려웠다. 내가 아는 Enum은 상수 값이었는데 자바에서는 객체라 그 차이점을 모르니 처음에는 적용하기 어려웠던 것 같다. 공부하며 클래스를 상수처럼 사용할 수 있고, 서로 관련 있는 상수 값들을 한 번에 관리할 수 있다는 점을 배웠다.
이를 당첨 여부와 그에 따른 상금 등의 정보를 관리하는 데에 적용하니 코드가 훨씬 깔끔해졌다. 각 당첨 정보와 그에 따른 부가 정보들을 한 번에 관리할 수 있어 코드를 작성하기에도 편했고, 모든 타입들이 하나의 Enum으로 관리되니 가독성 또한 좋아졌다.
또한 로또와 관련된 조건들(당첨 번호 갯수, 로또 번호 범위)이 여러 클래스에서 사용되어 처리 방법을 고민하며 Enum 클래스와 상수 클래스에 대해서도 공부할 수 있었다.
위의 조건들은 추가적인 부가 정보가 없어 상수 클래스로 관리했고, 이 과정을 통해 각 경우마다 적절한 클래스 사용에 대해 알 수 있었다.
일급 컬렉션
2주차 과제를 하며 자동차 객체(Car)를 선언하고, 입력받은 자동차 객체의 리스트(List<Car>)를 사용하였다. 이를 작성하며 Car를 사용하는 메서드들은 Car 객체에 넣었지만, List<Car>를 사용하는 메서드들은 어디에 두어야 할지 몰라 따로 클래스로 관리하였다.
하지만 List<Car>를 사용함에도 하는 일이 다른 경우는 클래스가 여러 개로 분리되어 코드를 알아보기 쉽지 않았던 점이 고민이었다.
이번 과제를 하며 주어진 Lotto 클래스를 사용하기 위해 일급 컬렉션을 공부하며 2주차에 고민했던 부분이 해결되었다. Lotto 또한 일급컬렉션이지만, List<Lotto>를 관리하는 Lottos라는 클래스를 만들어 관리했고, 이를 사용하는 메서드를 Lottos 안에서 관리할 수 있어 더 가독성 있는 코드를 작성할 수 있었다.
테스트 작성 이유
이번주까지 테스트 코드를 작성해보며 느낀 테스트 작성 이유는 '코드의 문제를 빠르게 발견할 수 있다'이다.
작은 단위 테스트부터 수행하였기에 하나의 동작에 대해서만 테스트를 수행하며 해당 기능이 의도한 기능을 수행하는지를 확인할 수 있었다. 그 과정에서 예외 사항에 대한 처리를 즉각적으로 할 수 있어서 여러 기능이 통합된 테스트를 작성하면서 생긴 에러에서도 문제를 빠르게 발견할 수 있었다.
이번 주는 프로그램이 늦게 완성 돼 프로그램 실행을 보기 위해 통합 테스트를 먼저 작성했던 점이 아쉬웠다. 단위 테스트를 하며 세세한 예외 처리 사항에 대한 에러를 수정하고, 통합 테스트에서는 생각하지 못 했던 예외 사항에 대해서도 처리할 수 있었다. 하지만 오히려 이 과정을 통해 단위 테스트의 중요성을 더 느낄 수 있었던 것 같다. 이를 통해 다음 주차 과제에서는 단위 테스트부터 시행하는 방식으로 진행해야겠다고 다짐했다.
마무리
4주차만을 남겨두고, 자바 문법과 객체 지향에 대해 프리코스 시작 전보다 익숙해진 듯 하다. 마지막 주차는 어떤 과제일지 궁금하기도, 잘 구현할 수 있을까 떨리기도 한다. 이번주차에 아쉬웠던 점들을 다음주에는 보완할 수 있도록 노력해야겠다.
-
사용 시 코드의 가독성이 높아지는 게 보여 최대한 사용해 보려 했다. 이번주차는 Set, Map 등 사용하는 컬렉션이 다양해짐에 따라 나오는 새로운 문법들이 생소하고, 복잡해진 걸 느꼈다. 문법이 어렵긴 하지만 익숙해진다면 편리할 것 같아 더 공부해보려 한다.
forEach vs stream.forEach
map stream entrySet? / stream method
factory method / public constructor vs factory method