2시간 혼자 하는 코드 리트릿: 프로덕션을 건드리지 않고 최악의 코드를 다시 쓰는 법
매주 2시간만 투자하는 ‘2시간 솔로 코드 리트릿’으로, 가장 문제 많은 레거시 코드를 안전하게 다시 써 보고 대담하게 실험하면서도 프로덕션 리스크 없이 기술 부채를 줄이는 방법을 소개합니다.
소개
어느 팀에나 꼭 하나씩 있는 그 코드가 있습니다.
아무도 손대고 싶지 않은 파일. 쓸데없이 모든 걸 알고 있는 God 클래스. 주석에 "이거 건드리면 다 터집니다" 같은 미신 같은 문구가 잔뜩 달려 있는 모듈.
스탠드업에서 투덜대고, PR에서는 살살 피해 가고, 다시는 이 부분을 건드리는 티켓이 안 오기만 바랄 뿐입니다. 그 사이 이 코드는 계속 더 많은 꼼수와 플래그, 두려움을 빨아들이며 괴물처럼 자라납니다.
그렇다면 그 코드를 정기적으로 다룰 수 있는 방법이 있다면 어떨까요? 다시 쓰고, 재구조화하고, 나중엔 다루기 즐거운 코드로 만들 수 있는데 — 프로덕션이나 일정에는 아무런 리스크도 주지 않는 방식으로 말이죠.
여기서 등장하는 것이 바로 **2시간 솔로 코드 리트릿(Two-Hour Solo Code Retreat)**입니다. 작고, 주간으로 반복 가능하며, 타임박싱된 연습으로, 가장 골칫거리인 코드를 격리된 공간에서 리팩터링하며, 실력을 키우고, 기술 부채를 안전하게 조금씩 갚아 나가는 방법입니다.
2시간 솔로 코드 리트릿이란?
2시간 솔로 코드 리트릿은 매주 일정으로 잡아 두고 다음을 수행하는 개인 연습입니다.
- 당신을 미치게 만드는 가장 나쁘고, 가장 위험하고, 가장 고통스러운 코드를 하나 골라서 복사합니다.
- 프로덕션과 완전히 분리된 안전한 환경에서, 딱 2시간 동안 혼자 작업합니다.
- 의도적으로 그 코드를 **다시 쓰고(rewrite), 리팩터링하고(refactor), 재설계(re-architect)**합니다. 필요하면 제약(condition/constraint)을 걸고 진행합니다.
- 결과물은 필요하다면 과감히 버리고, 나중에 쓸 만한 부분만 골라서 가져옵니다.
이 방식은 고전적인 Code Retreat 형식에서 영감을 받았습니다. 반복적인 학습, 작은 실험, 더 나은 설계를 강제하는 제약 같은 원칙 말이죠. 하지만 게임 오브 라이프 같은 장난감 문제를 페어로 푸는 대신, 혼자서 실제 레거시 코드, 바로 당신이 실제로 책임지는 코드를 다룹니다.
이 2시간의 결과는 새로운 기능도 아니고, 바로 머지할 PR도 아닙니다. 대신 이런 것들을 얻습니다.
- 그 지저분한 모듈을 위한 더 나은 설계 아이디어
- 나중에 실제로 적용할 수 있는, 더 안전한 리팩터링 전략
- 프로덕션 코드베이스에 통합할 수 있는 테스트, 패턴, 프로토타입
2시간 안에 “레거시 시스템을 고치는 것”이 목표가 아닙니다. 목표는 다음에 프로덕션에서 그 코드를 건드릴 때를 위해, 집중된 무위험 연습을 해 두는 것입니다.
왜 복사본으로 작업해야 할까? — 안전이 먼저
2시간 솔로 코드 리트릿의 핵심은 프로덕션으로부터의 완전한 격리입니다.
위험한 기능 플래그 뒤에서 작업하는 것도 아니고, 리팩터링을 메인 브랜치에 바로 푸시하는 것도 아닙니다. 대신 이렇게 합니다.
- 레포지토리를 클론하거나 복제해서 샌드박스를 만듭니다.
- 버려도 되는 브랜치에서 작업하거나, 아예 CI와 연결되지 않은 로컬 폴더에서만 작업합니다.
- 필요하다면 외부 의존성은 비활성화하거나, 더미/목(Mock)으로 대체합니다.
이렇게 해 두면 당신이 하는 어떤 작업도 실제 사용자에게 닿을 수 없으므로, 이런 이점을 얻습니다.
- 프로덕션 장애에 대한 두려움이 0이 됩니다. 미친 듯이 실험해도 됩니다.
- 실험의 자유를 얻습니다. 새로운 패턴, 과감한 구조 변경, 심지어 완전한 리라이트까지 가능합니다.
- 심리적 안전감이 생깁니다. 티켓, 스프린트, 승인 압박 없이 온전히 연습에만 집중할 수 있습니다.
아이러니하게도, 나중에 중요한 레거시 코드를 프로덕션에서 안전하게 수정하는 가장 좋은 방법은, 먼저 프로덕션 리스크가 전혀 없는 상태에서 마음껏 망가뜨려 보는 것입니다.
기존 코드 리트릿과 무엇이 다른가?
고전적인 코드 리트릿은(보통 하루 종일 진행되는 이벤트 형태) 다음에 초점을 둡니다.
- 페어 프로그래밍
- TDD를 활용한 장난감 문제 풀이
- 같은 문제를 여러 제약 조건으로 반복해서 풀기
- 각 세션이 끝날 때마다 코드 전부 버리기
2시간 솔로 코드 리트릿은 이런 원칙은 유지하되, 일상 업무에 맞게 다음과 같이 조정합니다.
- 페어가 아니라 혼자(Solo) 합니다. 누구와 일정 맞출 필요가 없어서, 주간 습관으로 유지하기 좋습니다.
- 장난감 문제가 아니라 실제 코드를 다룹니다. 실제로 유지보수하는 레거시/문제 코드에 손을 댑니다.
- 짧고 반복 가능합니다. 2시간이면 대부분의 주에 충분히 확보할 수 있습니다.
- **선택적 수확(Harvesting)**이 가능합니다. 결과물을 전부 버려도 되고, 그중 패턴, 테스트, 리팩터링 일부만 골라 실제 레포에 가져와도 됩니다.
여전히 제약 조건을 두고, 반복을 통해 학습하지만, 이번엔 그 결과가 당신의 실제 업무와 직접적으로 연결됩니다.
2시간 솔로 코드 리트릿 준비하기
이 연습은 크게 거창한 준비 없이도 시작할 수 있습니다. 다음과 같이 간단히 세팅해 보세요.
1. 적절한 코드를 고른다
다음 중 하나 이상에 해당하는 코드를 고릅니다.
- 모두가 변경을 두려워하는 코드
- 자주 버그나 장애를 일으키는 코드
- 복잡도가 높은 코드 (긴 함수, God 객체, 중첩된 조건문 투성이)
- 비즈니스에 중요하지만 테스트가 거의 없는 코드
처음부터 서브시스템 전체를 고르지 마세요. 대신 이렇게 시작합니다.
- 하나의 파일
- 한 개의 클래스나 모듈
- 하나의 API 엔드포인트나 유스케이스
범위가 작을수록 2시간 안에 의미 있는 진전을 만들 수 있습니다.
2. 안전한 샌드박스를 만든다
- 레포를 클론합니다.
- 눈에 잘 띄는 이름의 샌드박스 브랜치를 만듭니다. (예:
solo-retreat-auth-service) - 이 브랜치가 CI/CD를 통해 배포되지 않도록 확인합니다.
- 필요하다면 외부 연동은 Stub/Mock으로 대체해서 로컬에서 테스트가 돌 수 있게 합니다.
그리고 마음속으로 이렇게 다짐합니다: 이번 세션에서 만든 것은 하나도 머지하지 않아도 된다.
3. 2시간으로 타임박스 한다
2시간은 몰입 상태에 들어가기엔 충분히 길고, 매주 빼먹지 않기에도 부담스럽지 않은 길이입니다.
- 캘린더에 반복 일정으로 등록해 두세요.
- 미래의, 더 덜 스트레스 받는 나와의 약속이라고 생각하세요.
- 타이머를 사용하세요. 알람이 울리면, 아이디어 한가운데여도 그만합니다.
이 제약 덕분에 집중력이 생기고, 이 활동이 하루를 다 잡아먹지 않게 됩니다.
세션 동안 실제로 무엇을 할까?
2시간을 이렇게 나누어 사용할 수 있습니다.
단계 1: 탐색과 관찰 (15–20분)
- 코드를 훑어보며 뭐가 그렇게 아픈지 적어둡니다: 긴 메서드, 중복, 매직 넘버, 의미 없는 이름 등.
- 이 모듈이 무엇을 알고 있고, 무엇을 하고, 무엇에 의존하는지 대략적인 책임 지도를 (종이든 디지털이든) 스케치합니다.
- 테스트가 없다면 특성화 테스트(characterization test) 몇 개를 추가합니다. 현재 동작을 (완벽하지 않더라도) 있는 그대로 고정해 두는 테스트입니다.
목표는 기존 코드를 평가하거나 비난하는 게 아니라, 이해하는 것입니다.
단계 2: 제약을 고른다 (5분)
이 시간을 ‘그냥 수정’이 아닌 의도적인 연습으로 만들기 위해, 한두 개의 제약을 고릅니다. 예를 들어:
- TDD만 사용: 실패하는 테스트 없이는 프로덕션 코드를 작성하지 않는다.
- 최상위 함수엔 조건문 금지: 분기 로직은 모두 작은, 이름이 있는 메서드로 내려보낸다.
- 핵심 개념에 원시 타입 금지: 여기저기 문자열/정수만 넘기지 말고 값 객체(Value Object)나 타입을 도입한다.
- 중복 금지: 중복을 발견하면 반드시 리팩터링한다.
제약은 당신이 구조와 설계를 다르게 생각하게 강제합니다.
단계 3: 과감하게 리팩터링한다 (80–90분)
이제 본격적으로 들어갑니다.
- 괴물 같은 메서드에서 작은 함수나 클래스를 추출합니다.
- 더 나은 이름과 타입을 가진 도메인 개념을 도입합니다.
- 서드파티 호출을 인터페이스 뒤로 감춰 테스트 가능성을 높입니다.
- 작업 중 발견한 엣지 케이스에 대한 테스트를 추가합니다.
지금은 샌드박스라는 걸 기억하세요.
- 새로운 아키텍처 스타일(예: 헥사고날 아키텍처, Ports & Adapters)을 시도해 보세요.
- Strategy, State, CQRS 같은 패턴을 적용해 보는 실험을 해 보세요.
- 모듈을 레이어나 컴포넌트로 쪼갰을 때 어떤 느낌인지 시험해 보세요.
막혔다면:
- 30분 정도 작업하던 지점을 롤백하고 더 단순한 리팩터부터 다시 시도합니다.
- 세션 중간에 제약을 바꿔서 막힌 부분을 풀 수도 있습니다.
단계 4: 되돌아보고, 건질 건 건진다 (10–15분)
타이머가 울리면:
- 미래의 나에게 짧은 메모를 남깁니다.
- 무엇이 잘 먹혔는가?
- 어떤 설계가 유망해 보였는가?
- 어떤 리팩터링은 테스트가 더 없으면 실제 프로덕션에 적용하기 위험해 보였는가?
- 유용한 산출물을 챙깁니다.
- 실제 코드베이스에 있었으면 하는 테스트 케이스
- 더 나은 설계 스케치나 다이어그램
- 나중에 안전하게 포팅할 수 있는 리팩터링 코드 스니펫이나 패턴
오늘 당장 머지할 필요는 없습니다. 대신, 다음에 실제 제약 속에서 그 코드를 건드릴 때 활용할 플레이북과 도구 상자를 쌓는다고 생각하세요.
짧은 데일리 습관과의 궁합
2시간 솔로 코드 리트릿은 5분짜리 코드 카타, 짧은 TDD 연습, 일상 업무 속의 작은 리팩터링 같은 데일리 습관과 함께할 때 특히 효과적입니다.
- 매일: 이름 짓기, 테스트 작성, 작은 단위 리팩터링 같은 미시적 스킬을 연습합니다.
- 매주(2시간 리트릿): 더 큰 리팩터링, 아키텍처 변경, 실제 시스템에 설계의 경계(Seam)를 만드는 작업을 심도 있게 다룹니다.
데일리 루틴은 당신의 **손(기술, 문법, 기계적인 능력)**을 날카롭게 하고, 주간 리트릿은 **머리(설계, 전략, 레거시 다루기)**를 예리하게 만듭니다.
몇 주, 몇 달이 지나면, 처음에는 엄두도 안 났던 코드가 점점 손이 가는 코드로 느껴지기 시작합니다.
장기적인 효과: 두려움에서 장인 정신으로
정기적인 2시간 솔로 코드 리트릿은 시간이 지날수록 이런 복리 효과를 냅니다.
- 레거시 코드에 대한 두려움 감소. 이미 부담 없이 여러 번 다뤄 본 코드이기 때문입니다.
- 더 유지보수 가능한 컴포넌트. 샌드박스에서 나온 아이디어가 서서히 프로덕션에 스며들면서, 가장 나쁘던 영역이 점점 덜 무서워집니다.
- 리팩터링 직관 향상. 패턴이 더 빠르게 눈에 들어옵니다. “여긴 추출해야겠다”, “여긴 의존성 역전이 필요하다”, “여기엔 Seam을 만들어야겠다” 같은 감각이 생깁니다.
- 압박 상황에서의 자신감 상승. 긴급 패치가 레거시 코드를 건드려야 할 때, 완전히 처음부터 즉흥으로 하지 않습니다. 이미 여러 번 리허설을 해 본 셈이니까요.
- 장인 정신으로의 문화 전환. 동료들이 당신의 실험 결과(더 좋은 테스트, 줄어든 회귀 버그)를 보게 되면, 비슷한 연습을 따라 하기 시작합니다.
무엇보다, 레거시 코드에 반응만 하는 상태(“이거 안 깨뜨리려면 어떻게 하지?”)에서 벗어나, 그 코드를 능동적으로 다듬는 상태(“이걸 어떻게 안전하게 진화시킬까?”)로 옮겨 갑니다.
이번 주에 시작해 보기
거창한 허가를 받을 필요도 없습니다. 이번 주에 이렇게만 해 보세요.
- 캘린더에 2시간짜리 블록을 하나 잡습니다.
- 가장 괴로운 파일 하나를 고릅니다.
- 샌드박스 브랜치를 만듭니다.
- 테스트 몇 개를 추가하거나 개선합니다.
- 하나의 제약을 정하고 리팩터링을 해 봅니다.
- 배운 점을 정리해서 남겨 둡니다.
이게 전부입니다. 거대한 프로그램도, 조직적인 대변혁도 아닙니다. 단지, 프로덕션을 깨뜨리지 않으면서 최악의 코드를 다시 써 볼 수 있게 해 주는, 작고 반복 가능한 연습일 뿐입니다.
이걸 한 달만 매주 반복해 보세요. 그 무서운 코드 영역에 대한 당신의 감정이 어떻게 변하는지 유심히 관찰해 보세요. 시간이 지나면, 당신의 “최악의 코드”는 오히려 가장 많이 연습해 본 코드가 되어 있을 수 있습니다.
그리고 누군가가 “저 모듈은 아무도 건드리면 안 돼요”라고 말하는 순간, 당신은 속으로 조용히 이렇게 생각할 수 있을 겁니다. 나는 이미 건드려 봤다. 안전하게, 의도적으로, 그리고 분명한 계획을 갖고.