2주 차 미션이 끝나고 코드 리뷰를 통해 정말 많은 피드백을 받았고 정말로 완벽해 보였던 코드가 그제야 단지 코드뭉치에 불과했다는 사실을 알게되었습니다. 😱 피드백을 바탕으로 왜 그런 방식을 사용해야 하는지도 공부해 봤고 이번 미션을 진행하면서 적극적으로 해당 방식들을 적용시켜봤습니다.

먼저 MVC 패턴에 대해서 다시 생각해보게 되었습니다. 2주 차 미션에서는 컨트롤러와 서비스 레이어에서 대부분의 로직을 수행하고 객체를 만드는 일까지 수행했습니다. 또한 도메인 레이어는 값을 저장만 할 뿐 단순한 로직 외에는 별다른 역할을 수행하지 않았습니다. 이는 MVC 디자인 패턴의 정의에도 부합되지 않고 객체지향적으로도 안 좋은 방식이었습니다. 🥹

그래서 이번에는 서비스 레이어와 검증 레이어를 삭제해버리고 각 도메인 객체들이 알아서 일을 하도록 만들었습니다. 각자가 유효성 검증도 하고 관련된 로직(할당된 책임)을 처리하는 것입니다. 단순히 책임을 지는 곳의 위치만 바꾼다고 생각했는데 이런식으로 코드를 짜니까 전에는 컨트롤러에서 모든 일을 처리하는 느낌이었지만 이번에는 객체들이 서로 유기적으로 연결되어 객체들 간의 상호작용으로 로직이 처리되는 느낌이 들었고 객체지향이란 무엇인지 다시 생각해보게 되었습니다.🤔

가장 많이 지적 받은 것은 생성자였습니다. 생성자에서 하지 말아야 할 일을 하거나 접근 제어자를 public으로 만들어서 캡슐화도 되지 않았고 무엇보다 가독성이 별로 안 좋았습니다. 이번에는 대신 단 하나의 생성자를 매우 간소한 형태로 구현하였고 정적 팩토리 메서드를 통해 객체를 반환하는 방식을 적용시켜 보았습니다. 정적 팩토리 메서드는 생성자를 캡슐화 하고 호출하기도 더 쉬웠고 가독성도 월등히 좋았습니다. 그리고 이름을 부여할 수 있고 다양한 방식(사용자가 입력, 자동 생성, 인수로 생성)으로 객체를 생성할 때 구분하기 좋아진 건 덤이었습니다.🤭

확장성을 위해 상수를 저장하는 enum을 목적에 따라 분리하라는 지적을 받았습니다. 그래서 이번에는 총 6개의 상수 저장용 enum을 만들었고 enum의 이름을 보고 불러오고자 하는 상수를 찾기도 쉬워졌습니다.

입력값을 검증할 때 parseInt대신 정규식을 사용했습니다. 정규식 규칙을 적용시키는 것이 쉽지 않았지만 코드가 더 최적화 되었고 예외처리를 넘기기도 더 간단해졌습니다.

이것 외에도 정말 많은 코드 리뷰를 받았고 다른 사람들의 코드를 리뷰하면서 참고한 부분도 있었습니다. 코드 리뷰를 직접 미션을 진행하면서 반영해보고 정말 많이 성장했다는 기분이 듭니다. 🏋️‍♂️ 반면 코드 리뷰 외에도 혼자 고민하면서 성장했던 면도 있습니다.

view의 메서드들이 미션에서 주어진 입력만 처리했었는데 이는 재사용성이 떨어지는 코드입니다. 이에 대처하기 위해 이번 미션에서는 InputLong같은 더 범용적으로 쓸 수 있는 메서드로 구현했고 출력도 어쩔 수 없는 경우를 제외하고 예외 메시지나 시스템 메시지(일반 메시지)같은 범용적으로 사용할 수 있는 부분은 상수를 저장하는 enum을 인수로 받아서 enum에 저장된 상수를 출력하도록 범용적인 출력 형식을 적용해서 여러번 재사용했습니다.♻️

클래스(객체)를 분리하는 연습

객체를 적절히 분리하는 것은 어떻게 보면 추상적이고 어려운 일입니다. 저는 이번 미션을 진행하면서 총 8개의 도메인 클래스를 만들었습니다. 이 중 1개(WinningNumbersWithBonus)는 단순히 메서드의 파라미터를 줄이기 위해 만들어졌지만 나머지는 모두 각자의 책임을 가지고 있는 객체를 만드는 클래스들입니다. 앞서 반영한 피드백들이 클래스들이 단순히 값만 저장하는 시체같은 객체를 만들지 않고 각자의 책임을 수행하게 만드는 데에 도움이 됐습니다. 모든 객체는 스스로 검증하고 유기적으로 다른 객체와 상호작용합니다. 또 내부적으로 많은 기능을 수행하기 때문에 외부에서 객체를 사용하는 것은 역으로 매우 단순해졌습니다. 이는 프로젝트의 규모가 커질수록 특히 더 빛을 발할 것 같습니다. 🏢