우테코 프리코스가 시작됐다.
2시에 유튜브 라이브로 사전설명회가 있었고, 3시 땡 하니 1주차 미션 메일이 도착했다.
그런데 왠걸, 1주차 미션이 숫자야구였다.
사실 우테코 프리코스 미션은 어느정도 이전 기수의 문제를 그대로 쓴다고는 알고 있었다.
5기때는 1주차 온보딩(기초 코딩테스트급 7문제) - 2주차 숫자야구였는데, 2주차 문제가 이번 기수 때 1주차 문제로 나온 것이다.
여기서 생각했던 것은,
1. 지원자 수가 많아서 우테코 측에서 변별력을 올린 것 같다.
2. 다행이다.
숫자 야구를 풀어봐서 다행이 아니었다. 나는 숫자야구는 포크만 해놓고 풀어보지는 않았다.
그럼 왜 다행이냐면, 한 과제에만 집중할 수 있었기 때문이다.
사실 지난 기수 프리코스 문제 중 1주차 온보딩에서 한 문제만 조금 풀어봤는데, 간단한 문제여서 그런지 한 클래스 안에 절차지향으로 구현하신 분들이 많았다.
그런데 나는 간단한 문제라도 객체지향을 적용해보고 싶었다. 객체지향을 배우고 실전에 자기주도적으로 써먹는건 처음이기 때문이었다.
link
내가 적용할려 했던 건 TDD, SRP(단일 책임 원칙), 클래스와 메소드 분리, 그리고 명확한 네이밍 딱 이 4가지였다. 아직 여러 디자인패턴이나 SOLID 원칙은 자세히 알지 못해 사용하기는 무리라고 생객했다.
아무튼 그렇게 해서 절차지향으로 하면 1-2시간만에 후딱 끝낼 문제를 이틀에 걸쳐 풀게 되었다.
한 문제도 오랜 시간이 걸렸는데, 7문제를 전부 그렇게 풀려면 시간이 얼마나 걸릴까.
물론 절차지향으로 풀어도 통과는 하겠지만, 객체지향으로만 해결하고 싶다는 똥고집 고집이 있었다.
그래서 다행이었다. 시간에 타협하지 않아도 돼서. 절차지향으로 해결하지 않아도 돼서!
잡다한 이야기가 좀 길었던 것 같다. 이제 진짜 1일차 회고를 얘기해보려 한다.
문제를 읽어보니, 대충 어떻게 해결해야 될 지 핵심 로직은 예상 되었다.
입력 받아오기 -> 파싱하기(크기가 정해져 있으니 아마 배열로 저장) -> 정답 숫자 랜덤 생성 -> 파싱한 숫자와 정답 숫자 비교 -> 출력
일단은 이걸 바탕으로 설계를 해야 했다. 내가 공부한 바, 객체지향에서 가장 중요한 것은 '설계' 였다. 객체지향적인 설계!
설계 단계에서 내가 활용하고자 한 것은,
1. 기능 목록
2. 흐름도
3. 유스케이스
였다. 이 중 기능 목록 작성은 '과제 진행 요구 사항' 에 포함되어 있기에, 당연히 해야 했다.
내가 처음에 생각한 기능 목록은 다음과 같았다.
어떻게 객체지향적으로 디자인 할 것인지는 나중에 생각하고, 일단은 필요한 기능들을 다 써 보았다. 초안이기에, 과제를 진행하며 추가되거나 삭제되는 기능(필수 기능을 제외하고)이 있을 수도 있다.
완성된 기능 목록을 바탕으로 흐름도를 러프하게 그렸다. 간단하게 '기능'과 '호출'만 적었다. 클래스 다이어그램이나 객체들의 협력 흐름을 적은 전문적인 흐름도가 아닌, 그냥 생각을 정리하고 설계를 돕는 나만의 흐름도이다. 이를 기반으로 다른 흐름도를 작성할 수도 있을 것 같다.
흐름도는 그리면서 생각하고, 지우고, 또 다시 그리고를 반복했다.
| 직접 그린 러프한 흐름도(1차). 화살표는 호출(또는 요청)한다는 뜻이다.
첫 번째로 저렇게 흐름도를 완성했는데, 입출력 요구 사항을 다시 읽어보니 바로 '입력 받은 수에 따라 게임 시작/종료 기능' 을 바로 실행하면 안 될것 같았다.
| 야구 게임 입출력 요구사항
게임을 일단 시작하고 끝난 후에야 1 또는 2를 입력해 게임 시작/종료를 선택하는 것으로 보여, 흐름도를 다시 수정했다.
그리고 기능 요구 사항에,
IllegalArgumentException
을 발생시킨 후 애플리케이션은 종료되어야 한다.라는게 있어서, 예외 발생 시 임의 메시지를 출력하지 않고 바로 IllegalArgumentException
을 발생시켜야 하는것으로 이해해, 예외처리 기능도 제외했다. (이 예외처리 기능은 내가 정한 에러 메시지를 띄우는 기능이다. 당연히 일반적인 예외 처리는 할 것이다.)
그래서 이렇게 최종 흐름도가 완성이 되었다.
유스케이스는 내가 감명 깊게 읽은 책, [객체지향의 사실과 오해] 에 나온다.
유스케이스란 이 책에서 정의하는 바, 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것이다. 나는 이 '상호작용의 흐름을 텍스트로 정리한다' 라는게 꽤 마음에 들어서, 유스케이스도 한번 사용해 보았다.
| 책의 유스케이스 예제
| 내가 작성한 유스케이스
여기까지 하는데 되게 오래 걸렸다. 흐름도도 단순히 기능의 흐름을 작성한 것이지, 객체에게 책임을 아직 분담하지는 않았다. 할 일이 산더미다.
그런데 이렇게 막상 설계를 하고 나니 뭔가 디자인 패턴도 사용해보고 싶었다. mvc, 옵저버, 전략 패턴 등등은 하나도 모른다. 그러나 이전 프리코스 온보딩 문제를 풀 때 보다는 조금 더 발전된 객체지향을 적용하고 싶었다.
그래서 적용하기로 한 건,
1. mvc 패턴
2. (필요시) 싱글톤 패턴
3. 클래스, 메서드 분리
답 : 그냥. 해보고 싶고 배워보고 싶으니까.
사실 mvc 패턴 사용에 대한 의구심이 좀 있었다. 이전 프리코스 후기들을 보니 대다수가 mvc 패턴을 사용하고 있었다. 그런데 '남들이 다 쓰니까, 나도 써야지' 는 좀 아닌 것 같았다. mvc 패턴도 당연히 장단점이 있을 건데, 장단점을 파악하지 못하고 '그냥' 쓰고 싶지는 않았다.
그런데 오늘 포비님과 왼손님이 프리코스 사전 설명회를 하실 때, 이런 말씀을 하셨다.
"(프리코스는) 합격의 목적도 있지만, 이 프리코스 자체가 여러분의 학습의 기회가 됐으면 좋겠다."
그래서 그냥 써보기로 했다. 일단 써보는게 빠르게 배우고 장단점을 파악하기 쉬울 것 같았다. 상대적으로 난이도가 좀 쉬운 1주차니 레고를 갖고 노는 어린아이의 마음으로 이것 저것 시도해보기로 했다.
조금 모른 채로 쓰면 어떤가? 이 자체가 학습의 기회인데. 패턴을 잘 사용하지 못해 받는 감점(있는지 없는지도 모르는)에 대한 걱정은 하지 않기로 했다. 프리코스 과정 자체를 학습의 즐거움으로 받아들이기로 했다.
싱글톤 패턴은 Java를 공부할 때 살짝 배웠었다. [이것이 자바다] 책에서 싱글톤 패턴을 설명하는 과정이 있었다. 싱글톤 패턴이 객체를 하나만 사용하여 관리할 때 쓴다고 하니, 뭔가 설정이나 상태를 관리할 때 사용할 수도 있지 않을까 싶었다.
추가로 전략(Strategy) 패턴도 배우고 사용해 볼까 했는데, 애플리케이션의 기능에 비해 오히려 오버 엔지니어링이 될 거 같아서 하지 않기로 했다.
디자인 패턴도 정했으니 일단은 테스트 코드를 작성해보려 했다. (mvc 패턴에 따른 설계와 객체에 책임을 부여하는 과정은 일단 코드를 좀 작성해본 뒤 감을 잡고 해보기로 했다.)
일단은 사용자에게 입력을 받는 부분부터 작성을 시작했다.
테스트 코드를 실행 했는데 입력을 건너뛰고 테스트가 실패했다.
알고보니 테스트 코드에서는 콘솔 입력을 사용할 수가 없었다.
다행히도 해결 방법은 쉽게 찾았다. 오늘은 시간이 늦어 내일 적용할 예정이다. 다만 예상치 못한 복병을 만나 조금 당황했다.
1일차는 이렇게 끝이다. 결과물은 적지만, 매우 많은 고민을 하게 된 시간이었다. 특히, '어떻게 좋은 객체 지향 설계를 할 것인가?' 에 대해 많은 고민을 했다. 흐름도를 작성할 때, 머릿속으로 코드의 호출을 계속 상상하면서 그리고, 설계 단계에서 계속 머릿속으로 시뮬레이팅을 했다. 설계가 가장 중요하다고 생각했기 때문에 시간이 아깝지는 않았다.
내일은 테스트 코드 이슈를 해결하고, 본격적으로 코드를 작성하려 한다.
assertThat()
을 사용할 때 assertThat
까지만 적으면 인텔리제이에서 인식을 못한다(자동 코드 완성이 안된다. 처음에 import 가 안 돼서 당황했다.) assertThat()
까지 해줘야 인식한다.