
TDD와 설계의 순서, 그리고 추상화에
“기물은 움직일 수 있다”에서 출발한 고민
이번 미션은 장기 구현. korean chess 장기를 페어 프로그래밍으로 구현해야 하는 미션이다. 맨 처음 우리에게 주어진 요구사항은 두 개였다.
- 장기판의 장기말들을 초기화해라.
- 장기판의 말들은 움직일 수 있다.
페어와 나는 먼저 1번을 끝내고 그 뒤에 2번 요구사항을 시작할 때가장 작은 단위의 테스트로 “기물은 움직일 수 있다” 를 출발점으로 잡았다. 그렇게 우리의 TDD 여정은 시작됐다.
당시 우리는 enum 기반으로 각 기물의 움직임을 구현했고, 이를 중심으로 Piece 코드를 작성해나갔다. 나는 사실 각 기물을 개별 클래스로 나누고 싶었지만, 당장 그렇게 해야 할 명확한 이유를 찾지 못해 설득력 있는 리팩토링 방향을 잡지 못했다.
그런데 다른 크루들과 이야기를 나누면서 놀라운 점을 발견했다. 많은 크루들이 요구사항 2를 기준으로 시작해서 “킹은 움직일 수 있다”처럼 구체적인 테스트부터 시작했고, 자연스럽게 King, Knight, Rook 같은 개별 클래스를 만들고 구현을 이어간 것이었다.
왜 나는 enum으로 시작했을까?
사실 나도 기물들을 개별 클래스로 만들고 싶었다. 그런데 왜 그래야 하는지에 대한 이유를 찾지 못했고, 우리가 작성한 “기물은 움직일 수 있다” 테스트는 enum으로도 충분히 만족되었기에, 별도의 클래스로 나눌 필요성을 느끼지 못했다.
하지만 TDD를 진행하면서 느꼈다. 앞으로 설계가 복잡해질수록 결국엔 각 기물이 별개의 클래스가 되는 것이 자연스럽고 유지보수에도 유리할 것이라는 걸. 문제는, 언제 그 타이밍이 오는가였다. 그리고 **“당장은 필요 없어 보이는 이 설계를 어떻게 설득할 수 있을까”**라는 질문이 떠올랐다.
리뷰어에게 던진 질문과 답변
그래서 리뷰어에게 이런 질문을 던졌다.
설계를 하지 않고 TDD를 진행한다면, 시작 테스트를 무엇으로 잡느냐에 따라 구조가 크게 달라진다는 걸 느꼈습니다.
이게 맞다면 TDD를 할 때 단순히 가장 작은 테스트부터 시작하는 게 아니라, 어느 정도 설계를 먼저 한 후에 TDD를 진행해야 하지 않을까요?
이에 대한 리뷰어의 답변은 나에게 큰 전환점이 되었다.
설계를 완전히 배제할 순 없어요. 적절한 추상화는 필요하지만, 구체적인 설계는 테스트를 통해 구체화해가면 좋습니다.
TDD에서 중요한 건 추상화의 정도를 적절히 조절하는 겁니다. “기물은 움직일 수 있다”처럼 추상적인 테스트보다,
“병은 앞/옆으로 한 칸 움직일 수 있다”처럼 도메인 규칙 기반의 테스트가 더 구체적인 설계를 유도할 수 있었을 거예요.
‘순서’가 중요한 게 아니었다
이 피드백을 통해 나는 중요한 사실을 깨달았다.
내가 enum 기반으로 설계를 진행하게 된 건, 단순히 ‘순서’를 그렇게 잡았기 때문이라고 생각했다. 기물을 먼저 초기화했고, 자연스럽게 PieceType을 사용했으니, “기물은 움직일 수 있다”라는 테스트부터 시작할 수밖에 없다고 여긴 것이다.
하지만 이건 착각이었다. ‘순서’ 때문이 아니라, 내가 이미 추상화를 한 상태에서 시작했기 때문이었다.
사실 나는 처음부터 Piece라는 추상 개념을 만들고, 그 아래에 PieceType enum을 둠으로써 초기 설계 자체가 추상화된 상태였다. 반대로 각각의 기물을 개별 클래스로 만들고 나중에 Piece로 추상화했다면 전혀 다른 구조가 나왔을 것이다.
객체는 정말 "단순한 조각"부터 시작해야 한다
TDD에서 가장 작은 단위의 테스트를 고르는 것은 단순히 “작다”는 기준이 아니다.
추상화의 정도가 얼마만큼 들어가 있는가가 더 중요하다.
예를 들어, 이전 미션에서 다뤘던 트럼프 카드도 마찬가지다. '카드'라는 개념 자체가 추상화의 산물이다. 현실에는 각각의 52장 카드가 존재할 뿐이고, 우리는 그것들을 일반화해서 '카드'라고 부른다.
그렇기 때문에 TDD에서도 “카드를 뽑을 수 있다”라는 테스트는 이미 추상화된 테스트다.
우리가 인간인 이상 추상화를 피할 수는 없지만, 그 사실을 인지하느냐 아니냐는 큰 차이를 만든다.
그래서 나는 이제 이렇게 생각한다
TDD를 할 때, 가능하면 추상화를 최소화한 상태에서 출발하고,
진짜 필요한 순간에 추상화를 적용해 나가는 것이 훨씬 자연스럽고 설득력 있는 구조를 만들 수 있다.
처음부터 추상화하고 시작하면, 나중에 구조를 바꾸는 게 아니라 추상화 방식을 바꾸는 일이 되기에 훨씬 더 어렵다.
이건 단순한 리팩토링이 아니라 기존 사고방식과 설계를 통째로 뒤엎는 작업이기 때문이다.
마무리하며: 설계와 추상화, 그리고 나의 새로운 시작
이번 TDD 경험은 단순한 코딩 실습을 넘어, 설계란 무엇인가, 어디까지 추상화하고 시작해야 하는가,
TDD는 어떤 순서와 구조로 진행해야 더 효과적인가에 대한 깊은 통찰을 주었다.
앞으로는 가장 단순한 조각부터 시작하고 추상화의 정도를 의식하며 필요한 순간에 설계를 넓혀가는 방식을 택하려 한다.
TDD는 테스트로 코드를 짜는 방식이 아니라, 사고의 방식을 바꾸는 도구라는 걸 다시금 느꼈다.
'개발 > 우아한 테크코스' 카테고리의 다른 글
Entity 와 VO, 논리적 식별자 고민 (3) | 2025.04.28 |
---|
