- Published on
우아한테크코스 5기 백엔드 프리코스 4주차 후기 - 다리 건너기 게임
지난 한 달간 진행됐던 프리코스가 오늘로서 끝이 났다. 프리코스 첫날 '이걸 어떻게 한 달 내내 해~~'라며 두려워하던 기억이 생생한데 막상 끝나고 나니 아쉬운 마음뿐이다. 그만큼 소중한 경험이라 그런 생각이 드는 것 같다. 많이 배워갈 수 있던 소중한 시간이었다. 🥰 그럼 마지막 4주차 회고 시작!
클래스 설계 이야기
이번 미션을 진행하며 가장 어려움을 느끼고, 시간을 많이 투자했던 부분이다. 1~3주차 미션과 달리 이번 미션에서는 활용해야 할 클래스와 각각의 클래스에 대한 제약 조건이 주어졌는데, 생각해야 할 것들이 많아 깊은 고민이 필요했다.

처음 며칠간은 코드를 아예 치지 않았다. 대신 책상에 공책과 A4 용지를 펼쳐두고 주어진 코드를 이해하고, 요구 사항을 꼼꼼히 확인하며 전체 프로그램을 설게하는 과정에 집중했다. 그 과정에서 다음과 같은 것들을 새로 알고 활용해보게 되었다.
- 함수형 인터페이스
주어진 코드를 분석하는 과정에서 함수형 인터페이스에 대해 새로 알게 되었다. 처음에는 왜 굳이 함수형 인터페이스를 하나 생성하고 이 인터페이스를 implements하여 BridgeRandomNumberGenerator를 만드는지 궁금했는데 나중에 테스트 코드에서 BridgeNumberGenerator를 implements하여 구현된 TestNumberGenerator가 사용되는 것을 보고 '아 이래서..!'하고 감탄했다.
- Controller
지금까지 많은 분들이 MVC 패턴을 기반으로 미션을 진행하셨다. 많은 분들이 사용하시는 것을 보고 흥미가 생겼지만 아직 MVC 패턴에 익숙지 않아 직접 활용해보진 못했는데, 이번 주차에 스스로 Controller의 필요성을 느끼게 되었다. UI 로직과 도메인 로직이 서로 연관이 없는 설계를 하기 위해 두 로직에 모두 접근할 수 있는 계층의 클래스가 필요했다. 완전한 MVC 패턴을 활용하진 않았지만, MVC 패턴의 Controller 개념을 차용하여 BridgeGameController라는 클래스를 만들어보았다.
나의 클래스 설계
긴 고민 끝에 이런 설계를 최종으로 완성해보았다! 😆 클래스 설계 과정에서 아래와 같은 생각을 해보게 되었다.

각 클래스의 역할과 클래스 사이의 관계
컨트롤러의 도입을 통해 도메인 로직과 UI 로직을 완전히 분리할 수 있었다. 1주차에는 하나의 클래스에 모든 기능을 작성했고, 2주차에는 도메인 로직(당시에는 이 말도 몰랐다)과 입력 로직만을 분리했고, 3주차에는 도메인 로직과 UI 로직을 나누긴 했지만 완전히 분리하진 못했다. 도메인 로직에서 입출력을 함께 수행하는 등.. 느리고 작은 성과긴 하지만, 이번 4주차에는 도메인 로직과 UI 로직을 완전히 분리하였다는 점이 만족스럽다.
내가 설계한 부분은 아니고 기존에 제공된 코드에 있던 설계이다. 다리 객체의 생성을 Bridge의 생성자에서 담당하지 않고 다리 생성을 담당하는 별도의 BridgeMaker 클래스가 있는 것을 보고 객체 하나의 책임을 최소로 한 좋은 설계라는 생각이 들었다.
나의 설계상, BridgeGame 객체의 현재 상태를 SUCCESS, FAIL, CONTINUE 중 하나로 표현해 컨트롤러가 이를 받아볼 수 있어야 했다. 어떤 방식으로 게임의 현재 상태를 나타낼지 고민하다가 3주차에 새로 알게 된 Enum을 활용해보았다. SUCCESS, FAIL, CONTINUE의 값을 가질 수 있는 Enum GameStatus를 만들어 코드 상에서 게임의 상태가 GameStatus.SUCCESS와 같이 표현되게 하였다. 단순히 세 가지 상태를 나타내기 위한 임의의 상수를 만들어 사용하는 것보다 훨씬 직관적이고, 제3자의 시선에서 이해하기 용이할 것이라 생각했다.
각 객체가 하나의 책임만을 갖도록 객체의 역할과 책임을 최소한으로 하여 설계하였는지는 의문과 아쉬움이 남는다. BridgeGameController와 Bridge의 역할이 너무 비대한 것 같다. 내 생각에 Bridge 클래스에 있는 몇몇 메소드는 '다리' 객체보다는 하나의 '게임' 객체나 아님 '출력' 객체의 책임에 더 가까운 것 같다. 도메인 로직에서 UI 로직을 건드려서는 안 된다는 원칙과 기존에 주어진 클래스와 관련된 여러 요구사항을 지키는 과정에서 따끈따끈한 스파게티 탄생..🍝 이 부분에 대해서는 커뮤니티에 한 번 다른 분들의 의견을 여쭙고 코드 리뷰를 받아 개선을 하고 싶다.
리팩토링
이번주 미션에서도 마찬가지로 작성한 코드를 리팩토링해보는 경험을 했다. 특히 이번주 미션의 여러 요구사항 중 가장 까다롭게 느껴졌던 것이 바로 함수 길이 10라인 제한이었다. 사실 지금까지의 제한이었던 15라인은 함수가 하나의 역할만 제대로 하게 구성한다면 그닥 어렵지 않게 자연스레 지킬 수 있었다. 그러나 10라인을 맞추기는 꽤나 쉽지 않았고, 10라인을 맞추기 위해 '어떻게 하면 이 함수를 더 나눌 수 있을까?'라는 고민을 계속 하게 되었다. 처음에는 분리를 위한 분리를 한다는 생각이 들어 아리송했는데 계속 하다보니 내 스스로 '아 이렇게 더 나눌 수 있었구나', '이건 바로 return을 해주는 게 좋았겠구나' 등 그 필요성을 느끼게 되었다. 쉽지 않은 시도였지만, 주어진 사항을 지키는 과정에서 내 코드를 더 나은 방향으로 개선하기 위한 고민을 해볼 수 있어 좋았다!
프리코스 완주 🐢
많은 낯선 것들을 만나 몸소 부딪히고, 그 과정에서 스스로 성장할 수 있었던 소중한 한 달이 이렇게 끝이 났다. 나의 부족함을 알기에 솔직히 아쉬움이 많이 남는 것도 사실이다. '더 열심히 했다면' 하는 미련도 계속 남는다. 소중한 기회라고 생각하며 임했던만큼 결과를 떠나서도 아쉬움이 남는 건 어쩔 수 없는 것 같다.
그러나 결과를 떠나 이 한 달은 나에게 매우 값진 시간이었다. 사실 우테코 합격만이 목표였다면, 1주차 때 급한 일이 생겨 종일을 병원 로비에 머물며 펑펑 울며 코딩을 하고 결국 몇 문제만을 풀고 테스트 점수 2/12의 초라한 결과를 제출했을 때 '솔직히 합격은 힘들어졌을텐데, 현실적으로 이걸 계속하는 게 맞나' 고민했을 것이다. 그러나 이 기간은 단순히 평가 과정이 아니라 스스로 많은 것을 배워갈 수 있는 기간이라고 생각했고, 프리코스 참여 동기가 단순 외적 요인이 아닌 나 스스로에게 있었기에 끝까지 완주할 수 있었던 것 같다.
실제로 이번 프리코스를 통해 내가 배우고, 스스로 고민했던 모든 것들은 결코 헛된 것이 아니었고 나에게 소중한 지식과 경험이 되어 주었다. 천 명이 넘는 사람들이 참여한 이 마라톤에서 비록 나는 앞장서는 토끼는 아니었지만, 나름대로 나만의 속도로 계속 나아가던 거북이었다 😁 이런 좋은 기회에 참여할 수 있었음에 감사하다!
이번 프리코스를 통해 나는
- 처음 써 본 언어인 자바를 다룰 수 있게 되었다.
- 프로그램을 어떻게 설계할 것인지 고민해보는 경험을 했다.
- 도메인 로직과 UI 로직의 분리를 이해하고 여러 객체로 프로그램을 설계할 수 있게 되었다.
- 코드 컨벤션을 준수하고, 좋은 네이밍을 계속 고민하며 가독성 좋은 코드를 고민할 수 있게 되었다.
- 기능 목록을 작성하고 기능 단위 커밋을 할 수 있게 되었다.
- 테스트 코드를 작성할 수 있게 되었다.
- 좋은 코드는 어떻게 작성해야 하는지 그 기준을 알게 되었다.
- 그 기준을 바탕으로, 직접 리팩토링을 수행하는 경험을 해보았다.
- 공동의 목표를 위해 함께 성장하는 경험의 기쁨을 다시금 느꼈다.
앞으로 더 성장하기 위해 나는
- 좋은 설계를 하기 위해 더 많은 것을 배우고 노력할 것이다. 객체지향, 디자인 패턴 등.
- 자바를 더 공부할 것이다. 자바를 사용한 간단한 구현은 할 수 있게 되었지만, 내가 기존에 사용했던 언어에는 없는 자바의 여러 기능에 대해서는 아직 경험이 부족하다.
- 테스트 코드의 작성과 활용법을 더 공부할 것이다. 제일 많은 아쉬움이 남는 부분이다.
- 프리코스 때 그러했던 것처럼, 처음 접하는 낯선 지식을 두려워하지 않고 나의 부족함을 알아가기 위한 공부를 할 것이다.