🎯 목표

저는 2주차의 공통 목표 뿐 아니라 1주차때의 개인 목표를 같이 병행했습니다. 2주차 개인 목표는 README를 단순한 설명서가 아닌 살아있는 문서로 유지하는 것, 그리고 기능 구현보다 테스트를 먼저 작성하는 TDD 방식을 도입하는 것이었습니다.


🧩 살아있는 문서를 위한 시스템 도입

이번 미션을 진행하며, 살아있는 문서를 만드는 습관을 기를 수 있었습니다. 개발을 시작하기에 앞서 프리코스 전반에 유용하게 활용할 수 있는 기능 명세 템플릿을 직접 구성했고, 이를 기반으로 전체 개발 흐름을 체계적으로 정리해 나갔습니다.

먼저 기능을 입력, 출력, 핵심 기능의 대분류로 나누고, 각 항목마다 어떤 데이터가 입력되고 출력되어야 하는지, 어떤 기능이 구현되어야 하는지를 명확히 정리했습니다. 그리고 대분류 아래에는 기능과 예외 상황을 한 쌍으로 구성하여 어떤 점에 유의해서 개발해야 하는지 사전에 점검할 수 있도록 했습니다.

여기에 더해, 기능 개발 상태를 한눈에 파악할 수 있도록 ☑️(개발 전), 🏁(개발 중), ✅(개발 완료)와 같은 상태 표시 아이콘을 도입했습니다. 이를 통해 문서만 보고도 전체 개발 현황을 직관적으로 파악할 수 있었고, 기능 구현 도중에도 변경 사항을 실시간으로 반영하며 문서를 계속 업데이트해나갈 수 있었습니다.

이러한 과정을 통해 1주차 미션에서는 놓칠 수 있었던 예외 상황과 유효성 체크 항목을 사전에 검토할 수 있어 실제 개발 과정에서도 큰 도움이 되었습니다. 단순히 문서를 작성하는 것을 넘어 문서로 개발을 이끌어가는 경험을 해볼 수 있었고, 이를 통해 개발 흐름 제어에 대한 자신감도 생겼습니다.


🧪 TDD를 하면서 느꼈던 장점과 단점

이번 미션에서는 문서 작업뿐만 아니라, TDD(Test-Driven Development) 방식에 도전해보며 개발 방법론에 대해 깊이 고민해볼 수 있는 시간을 가졌습니다.

TDD의 가장 큰 장점은 테스트 코드를 먼저 작성함으로써 자연스럽게 예외 상황에 대한 고려가 선행된다는 점이었습니다. 테스트가 존재한 상태에서 기능을 구현하게 되다 보니 코드 품질의 하한선이 보장되는 안정감이 있었습니다. 덕분에 이후 리팩토링을 거치면서도 기존 기능이 깨지지 않는다는 확신을 가질 수 있었습니다. 따라서 TDD를 통해 더 완성도 높은 코드를 구현할 수 있었고, 처음에는 익숙하지 않았지만 점차 큰 도움이 된다는 것을 체감했습니다.

동시에 TDD를 실천하면서 불편함과 시행착오도 있었습니다. 가장 고민이 많았던 부분은 리팩토링 과정에서 여러 메서드로 기능이 분리될 때, 이 새롭게 분리된 메서드에 대해서도 TDD를 적용해야 하는가에 대한 문제였습니다. 원칙적으로는 메서드를 만들기 전에 테스트를 먼저 작성해야 합니다. 하지만 실제 개발 흐름에서는 기능 구현 중간에 메서드를 나누는 경우가 많다 보니, 기능 구현 속도가 많이 느려지는 문제가 발생했습니다.

또 하나의 어려움은 커밋 단위가 꼬이는 문제였습니다. 저는 ‘테스트 코드 작성 → 기능 구현 → 리팩토링’이라는 흐름에 따라 커밋을 나누어 개발을 진행했습니다. 하지만 하나의 기능을 구현하면서 여러 하위 메서드가 추가되는 경우, 이 흐름이 깨지기도 했습니다. 기능 A를 구현하는 과정에서 메서드 1과 2를 만들고, 각각을 구현하다 보면 의도치 않게 미완성된 코드가 함께 커밋에 포함되는 상황도 생겼습니다.

이를 해결하기 위해 저는 기능 전체를 테스트한 후 구현 도중 생긴 하위 메서드에 대해서는 리팩토링 단계에서 따로 테스트 코드를 작성하는 방식으로 규칙을 정했습니다. 이렇게 절충점을 찾아가며 TDD를 적용한 덕분에, 개발을 하면서 유연하게 적용할 수 있는 저만의 TDD 방식에 대해 고민해볼 수 있었습니다.

이번 도전을 통해 TDD가 단순한 도구가 아니라 코드 품질과 개발 흐름을 지탱해주는 사고의 틀이라는 점을 깨달을 수 있었고, 앞으로도 프로젝트마다 상황에 맞게 TDD를 적극적으로 활용해보고자 합니다. 결과적으로 TDD가 잘 지켜졌다고는 이야기 하지 어렵지만, 좋은 TDD, 좋은 코드를 위해서 어떤 생각과 능력을 길러야 하는지 알 수 있었습니다. 바로 어떻게 하면 구조가 꼬이지 않게 명확하게 기능을 나눌 수 있을까? 라는 생각을 꾸준히 해야한다는 것입니다.


🧱 객체에 책임을 부여하며 설계에 대해 다시 고민한 시간

2주차 미션에서는 객체에게 역할과 책임을 부여하는 설계 방식에 도전해보았습니다. 기존에는 객체는 단순히 데이터를 담는 용도로만 사용하고, 대부분의 기능은 서비스 계층에서 처리하는 구조에 익숙했습니다. 하지만 이번 미션에서는 도메인 객체 내부에 기능을 포함시키는 구조를 채택하면서 자연스럽게 객체 중심의 설계에 대해 고민하게 되었습니다.

이 과정에서 가장 크게 느꼈던 한계는 기존에 익숙했던 MVC 패턴과의 충돌이었습니다. 객체가 스스로 동작하도록 만들다 보니 어느 순간부터는 각 계층의 책임이 뒤엉키는 듯한 불편함이 들었고, 결국 RacingGame을 구현하던 중 서비스와 객체의 책임이 부딪혀 이를 해결하기 위해 화면만 몇 시간 동안 바라보았던 것 같습니다.

고민의 해결책으로 객체 내부의 기능을 다시 서비스로 감싸고, 이를 컨트롤러로 전달하는 방식으로 구조를 재조정했습니다. 단순히 패턴을 따르는 것이 아니라 지금 내가 겪고 있는 문제를 중심에 두고 설계를 유연하게 풀어가는 과정이 필요하다는 걸 깨달은 순간이었습니다.

이 경험을 통하여 디자인 패턴은 정답이 아니라 도구라는 것을 배웠습니다. 문제를 패턴에 끼워 맞추는 것이 아니라 문제에 맞는 구조를 설계해야 하며, 때로는 나만의 방식으로 조율된 패턴을 만들어낼 수도 있어야 합니다. 중요한 건 언제나 “이 설계가 왜 필요한가”에 대한 이유 있는 선택이라는 점을 배웠습니다.


🚀 개선 방향과 다음 목표

2주차 미션을 통해 TDD와 객체에게 책임을 부여하는 설계 방식 모두에 도전해보면서, 이 두 가지 시도 사이에 공통적으로 존재하는 하나의 중요한 개선점을 발견할 수 있었습니다.

바로 “잘 설계해야 한다”는 것입니다.

그동안 문서를 작성하면서 기능을 나누고, 예외를 정의하고, 개발 단계를 관리하는 데 집중해왔습니다. 하지만 결국 문서는 구현해야 할 기능을 나열한 것에 불과했습니다. 그것을 어떻게 구현할지에 대한 고민, 즉 설계가 뒷받침되지 않으면 기능은 흩어지고 일관성을 잃기 쉽다는 걸 깨달았습니다.

그래서 저는 3주차 미션부터는 기능을 구현하는 이유와 방식에 대한 명확한 설명이 가능한 이유 있는 설계를 목표로 삼기로 했습니다. 기능을 나열하는 데서 멈추지 않고, 왜 이런 구조로 만들었는지를 설명할 수 있는 설계를 지향하려 합니다.

이를 위해 개인적으로는 객체지향과 디자인 패턴에 대한 기초를 혼자 학습하며 설계의 기반을 다지는 것부터 시작하려 합니다. 동시에, 1주차부터 함께한 대면 스터디 팀원들과는 『객체지향의 사실과 오해』라는 책을 함께 읽고 객체지향적 사고에 대한 토론과 함께 관점을 확장해나갈 계획입니다.


이번주도 부족하고 긴 글 읽어주셔서 감사합니다!