목차
- ✏️ 4주차 문제
- 📃 추가된 요구 사항
- 🍋 지난 주보다 개선된 점
- 👋 프리코스를 마무리하며
위아래 둘 중 하나의 칸만 건널 수 있는 다리를 끝까지 건너가는 게임이다.
- 위아래 두 칸으로 이루어진 다리를 건너야 한다.
- 다리는 왼쪽에서 오른쪽으로 건너야 한다.
- 위아래 둘 중 하나의 칸만 건널 수 있다.
- 다리의 길이를 숫자로 입력받고 생성한다.
- 다리를 생성할 때 위 칸과 아래 칸 중 건널 수 있는 칸은 0과 1 중 무작위 값을 이용해서 정한다.
- 위 칸을 건널 수 있는 경우 U, 아래 칸을 건널 수 있는 경우 D값으로 나타낸다.
- 무작위 값이 0인 경우 아래 칸, 1인 경우 위 칸이 건널 수 있는 칸이 된다.
- 다리가 생성되면 플레이어가 이동할 칸을 선택한다.
- 이동할 때 위 칸은 대문자 U, 아래 칸은 대문자 D를 입력한다.
- 이동한 칸을 건널 수 있다면 O로 표시한다. 건널 수 없다면 X로 표시한다.
- 다리를 끝까지 건너면 게임이 종료된다.
- 다리를 건너다 실패하면 게임을 재시작하거나 종료할 수 있다.
- 재시작해도 처음에 만든 다리로 재사용한다.
- 게임 결과의 총 시도한 횟수는 첫 시도를 포함해 게임을 종료할 때까지 시도한 횟수를 나타낸다..
다리의 길이는 3 ~ 20으로 제한되어 있으며, 이동 방향은 위(U), 아래(D) 2가지입니다.
만약 잘못된 방향으로 이동하면 실패하고, 재시작 여부를 선택할 수 있습니다.
재시작을 하면 다리는 그대로 유지되고, 어떻게 이동할지 처음부터 다시 입력할 수 있습니다.
📃 추가된 요구 사항
- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다.
지난 3주차 미션의 경우 함수의 길이가 15라인을 넘지 않도록 구현하는 요구사항이 있었습니다.
사실 평소에 함수를 짧게 작성하는 습관을 가지고 있었기에, 지난 요구사항에는 큰 무리없이 진행할 수 있었습니다.
하지만 10라인까지 제한되다보니, 가독성을 위해 한 줄을 띄는 것도 부담스럽게 느껴졌습니다.
이번 주차에서 공통 메일로 리팩토링을 권한 이유가 여기 있었습니다.
따라서, 처음부터 10라인으로 작성하기 보다는, 이후에 차근차근 리팩토링하며 함수를 더 잘게 분리하는 방법을 선택할 수 있었습니다.
- 메서드의 파라미터 개수는 최대 3개까지만 허용한다.
지난 미션까지는 파라미터의 개수에 제한이 없었습니다.
그렇다고 파라미터를 3개를 넘기는 일도 없기는 했지만, 이번 주 과제에서는 생각보다 메서드에 파라미터를 사용할 일이 많았습니다.
특히, 게임의 중간 결과를 다루기 위한 로직에서 다수의 파라미터가 필요했습니다.
처음에는 Pair 또는 Triple를 통해 값을 return하였지만, return할 종류가 많아지자 각 요소가 어떤 값을 의미하는지 파악하기도 어려워보였습니다.
이러한 문제를 data class를 사용하여 해결하였습니다.
data class RoundResult(
val round: Int, // 진행하고 있는 라운드
val result: Result, // 게임 성공 여부
val playerRoute: RouteMap, // 플레이어 이동 루트
val tryCount: Int // 전체 게임 시도 횟수
)
다수의 파라미터 필요없이 각 라운드의 결과값을 가지고 있는 RoundResult 클래스를 통해 한 번에 값을 래핑하여 전달해주었습니다.
관련된 필드끼리 뭉쳐있기 때문에 매 라운드마다 어떠한 결과가 반환되는지 한 눈에 확인할 수 있었습니다.
🍋 지난 주보다 개선된 점
지난 주 아쉬웠던 점은 MVC을 제대로 이해하지 못했다는 부분이었습니다.
그렇기 때문에 이번 주에는 각 역할별로 controller, service, domain, view를 명확히 구분하였습니다.
추가된 요구사항을 잘 읽어보면 주어진 BridgeGame에서 InputView와, OutputView 사용을 제한하고 있습니다.
그렇다고 InputView, OutputView를 퍼사드(Facade) 패턴처럼 여러 서브시스템들의 작업들을 하나의 통합된 인터페이스로 제공하는건 너무 꼼수같아보였습니다.
제한 사항에서 원하는 것은 BridgeGame에서 단순히 View 클래스를 사용하지 않는 것이 아니라, 입출력 자체를 기존과는 다른 형태로 하기를 유도하는 것처럼 느껴졌습니다.
따라서 제공된 BridgeGame을 Service로 사용하고, 별도의 Controller를 통해 입출력을 대신하도록 하였습니다.
👋 프리코스를 마무리하며
우테코는 늘 스스로 생각해볼 수 있는 기회를 주는 점이 참 좋았습니다.
특히나 이번 과제는 근래에 어느 때보다 가장 고민을 많이 하게 만들어준 계기를 제공해주었습니다.
프로그래밍을 하면서 누군가에게 자문하는 것도 좋은 방법이라고 생각하였지만, 어느샌가 그 전에 충분히 스스로 사고하고 고민하는 본인의 모습을 발견할 수 있었습니다.
Class의 변경 유뮤, 특정 Class에서 I/O를 금지하는 요구사항 등 고려할 요소들이 늘어나면서 힘들기도 했지만, 한편으로는 고민과 스스로 구글링하는 과정을 통해 더 다양한 지식을 얻을 수 있었습니다.
그리고 위 요소들이 각각 어떤 의미를 포함하고 있는지도 고민해보았습니다.
(제가 고민한 결과는 이렇지만, 실제로 출제자님의 의도와 다를 수 있음을 가정하고 작성하겠습니다..!!)- BridgeGame이라는 서비스 레이어가 I/O와 직접 의존하지 않고, 중간에 Controller 라는 레이어를 통해 서비스의 재사용성을 높일 수 있다는 사실을 알 수 있었습니다.
- 패키지를 자유롭게 변경할 수 있다는건 각 클래스를 모듈 단위로 나누라는 의미로 받아들이고, 역할에 맞게 나누어보는 경험을 할 수 있었습니다.
- Early return pattern을 적용해보면서 특정 값이 반환되는 case를 쉽게 파악할 수 있었습니다. (클린 코드)
- 코틀린의 by 키워드를 사용하여 일급 컬렉션을 필드로 가지고 있는 컬렉션으로 delegate 해볼 수 있었고, 컬렉션 인터페이스를 implement 하기 때문에 실제 본인이 만든 컬렉션 자료구조처럼 활용할 수 있었습니다.
이번 과제를 포함하여 지난 프리코스 기간 동안 새롭게 알게 된 사실이 너무나도 많습니다.
모르는 지식을 새롭게 배우는 것이 힘들기도 하였지만, 오히려 재밌고 유익한 기억이 더 많았기에 4주만으로는 아쉽다는 생각이 많았습니다.
남은 코딩테스트 발표 기간 전까지 열심히 준비해서 10개월의 결실을 만들어보고 싶습니다.
프리코스를 준비해주신 우테코 관계자분들에게 감사의 말씀 드립니다 :)
github : https://github.com/tmdgh1592
'대외활동 > 우아한테크코스' 카테고리의 다른 글
[우아한테크코스] 2주차 - TDD(Test Driven Development) (1) | 2023.02.15 |
---|---|
[우아한테크코스 5기] 1주차 회고 - (양념 반 후라이드 반) 설렘 반 걱정 반 (6) | 2023.02.13 |
[우아한테크코스 5기] 프리코스 3주차 회고 - Kotlin 안드로이드 (1) | 2022.11.23 |
[우아한테크코스 5기] 프리코스 2주차 회고 - Kotlin 안드로이드 (2) | 2022.11.17 |
[우아한테크코스 5기] 프리코스 1주차 회고 - Kotlin 안드로이드 (2) | 2022.11.06 |