기록하는 공간
우아한테크코스 7기 프리코스[BE] 3주차 회고: 혹시.. 나도 1등 당첨? 본문

프리코스 3주 차는 어땠나요?
3주 차는 개인적으로 지금까지 했던 미션 중 가장 어렵다고 생각한 미션이었다.
실제로 로또를 구매해 본 적도 없고 관심도 없어서 그런지 로또가 어떤 흐름으로 발매가 되는지, 번호는 어떻게 되는지 잘 몰랐다. 그래서 근본적인 로또에 대해 고민하며 시작하게 되었다.
미션에 임하는 자세 (목표)
이번 미션의 목표는 1, 2주 차에서 받은 코드 리뷰와 그동안의 회고를 바탕으로 코드를 개선하는 것이다.
그래서 코드 리뷰에서 받은 피드백을 근거를 찾아 적용하고, 또, 모든 코드에 의미를 담으려 한다.
피드백 수용, 코드를 사용한 근거는?
1) 나는 왜 생성자 내부에서 객체를 생성했는가
먼저 코드 리뷰에서 생성자 내부에서 객체를 생성하는 것보다 의존성 주입으로 변경하는 것이 어떻겠냐는 피드백을 받았다. 그래서 무작정 적용하지 않고, 왜 의존성 주입으로 변경해야 할지 그 이유를 찾았다. 어떤 구현체를 사용할지 외부에서 결정할 수 있어서 유연성이 높아진 다는 것이다. 그리고 테스트와 유지 보수를 위해 의존성 주입(DI)을 권장한다고 한다.
그렇기에 2주 차 때는 생성자 내부에서 객체를 생성했던 코드를 3주 차에서는 의존성 주입을 선택했다.
2) validator를 왜 클래스로 분리하게 되었는가
패키지 중 validator라는 패키지가 있다. 이는 예외 검증과 관련된 로직을 관리하는 역할이다. 이와 같이 예외 검증을 별도로 분리한 이유가 있다. model과 view에서 예외 검증 로직을 직접적으로 다루고 싶지 않았기 때문이다.
model이나 view는 단순히 사용자로부터 입력을 받아 전달하거나, 비즈니스 로직을 수행하는 역할에 집중을 하고, 검증은 별도로 validator 클래스에서 처리하는 것이 역할 분리 측면에서 더 적합하다고 생각했다.
또한, 사용자가 잘못된 값을 입력했을 때는 이를 다시 입력받는 상황이 필요하다. 이 경우, 검증 로직을 validator에서 수행하면 예외 상황에 대한 처리와 재입력을 쉽게 관리할 수 있으며, view는 단순히 오류 메시지를 출력하고 재입력 요청을 반복하는 구조로 간소화된다. 이를 통해 view와 model 간의 역할이 명확이 구분되기 때문에 예외 검증을 별도로 분리하여 관리하였다.
3) validator는 어디서 사용해야 하는가?
위와 같이 분리를 했으니 validator를 어디에서 사용할지 고민이 많았다. 처음 구현했을 때는 view에서 수행했었다. 그 이유는 사용자가 잘못된 값을 입력했을 경우 해당 부분부터 재입력을 받을 수 있도록 하기 위함이었다. 이렇게 하게 되면 사용자 경험을 개선하고, 잘못된 입력으로 인한 오류를 즉각적으로 처리할 수 있다고 생각했다.
하지만 view에서 예외 검증을 하게 되면서 여러 문제가 발생했다. 첫번째로 view에서 검증을 진행하게 되면 도메인 모델 로직에 대한 예외 테스트 코드를 작성하기 어려웠다. 즉, 도메인 모델의 유효성 검증을 제대로 테스트하지 못하게 된다.
두 번째로 view에서 validator를 사용하는 것은 일반적으로 권장하지 않는다. view는 사용자 인터페이스에 대한 책임만을 가져야 하며, 비즈니스 로직이나 데이터 검증과 관련된 책임은 model로 위임하는 것이 바람직했다. 그래서 결국 모든 입력 검증 로직을 view에서 제거하고 도메인에 위임하기로 했다. 이를 통해서 도메인 모델의 유효성을 독립적으로 테스트할 수 있게 되었고, 코드의 책임 분리를 통해 가독성과 유지 보수성을 높일 수 있었다.
4) 파싱을 util로 관리한 이유
util 클래스를 만들어 파싱을 관리한 이유는 로또 게임에서 문자열로 받은 입력을 숫자로 변환해야 하는 경우가 많기 때문이다. 입력이 많아지면서 controller에서 중구난방으로 파싱 로직을 관리하는 대신, 이를 하나의 util 클래스에서 처리하면 더 효율적이기 때문이다.
고민
불변성을 유지하며 리스트를 반환하는데 List.copyOf()와 Collections.unmodifiableList()가 있는데, 둘 중 차이점을 잘 몰라서 무엇을 사용해야 할지 고민했다.
그래서 차이점을 찾아본 결과
List.copyOf()는 새로운 불변 리스트를 만들어 원본 리스트의 변경에 영향을 받지 않고, Collections.unmodifiableList()는 원본 리스트의 불변 래퍼를 제공하기 때문에, 원본 리스트가 변경되면 그 변경이 반영된다고 한다. 그래서 나는 원본 리스트에 영향을 받지 않게 하기 위해서 List.copyOf()를 사용하였다.
마무리
이번 3주 차는 이전 주 차들보다 더 많은 고민과 생각을 하게 되었다. 이러한 고민들은 나를 성장할 수 있게 해주어서 고마웠다. 그리고 또, 코드 리뷰를 통해 코드를 보는 눈이 더 넓어졌고, 회고를 통해 나의 보완할 점을 찾을 수 있었다.
남은 4주 차도 고민할 점이 많이 생겼으면 좋겠다.
링크
> 코드: https://github.com/giwoong01/java-lotto-7/tree/giwoong01
> PR: https://github.com/woowacourse-precourse/java-lotto-7/pull/500
'회고' 카테고리의 다른 글
우아한테크코스 7기 프리코스[BE] 4주차 회고: 편의점이 싫어요. (0) | 2024.11.24 |
---|---|
우아한테크코스 7기 프리코스[BE] 2주차 회고: 부릉 부릉 부르응… (0) | 2024.10.30 |
우아한테크코스 7기 프리코스[BE] 1주차 회고: 오 쉬운데?(며칠 뒤) 아니구나.. (0) | 2024.10.24 |
구름톤 유니브 2기 벚꽃톤: 기억해봄을 개발하며 (0) | 2024.07.18 |
14일간의 첫 풀스택 개발 : 목표 달성, 도전과 성장 (0) | 2024.05.19 |