새 프로젝트를 시작할 때면 늘 같은 유혹이 찾아옵니다. 프레임워크 문서를 열고, 데이터베이스를 잡고, 엔드포인트를 연결하고, 일단 달리고 싶어집니다. 저는 그 충동을 딱 한 시간만 더 참고, 덜 화려한 일을 먼저 합니다. 도메인을 모델링하는 것이죠.
도메인 모델은 결국 시스템이 실제로 다루는 명사들과 그것들을 묶는 규칙입니다. 주문, 입찰, 정산. 어떤 상태를 가질 수 있고, 무엇이 그 상태를 바꾸며, 무엇이 항상 참이어야 하는가. 여기에 Postgres도, React도, 어느 클라우드에 올리는지도 끼어들 자리가 없습니다. 오직 문제 그 자체에 대한 이야기입니다.
여기서부터 시작하는 이유는, 모델이야말로 틀렸을 때 가장 비싼 부분이기 때문입니다. 프레임워크는 갈아끼우면 되고, 데이터베이스는 마이그레이션하면 됩니다. 하지만 핵심 추상이 비즈니스가 실제로 사고하는 방식과 어긋나 있으면, 그 뒤의 모든 기능이 결을 거슬러 갑니다. 코드는 특수 케이스로 가득 차고, 사실 그건 모델이 새고 있다는 신호입니다.
도움이 되는 습관 몇 가지가 있습니다.
- 일하는 사람들이 부르는 이름 그대로 부릅니다. 창고 팀이 “위탁(consignment)“이라고 하면, 코드도
consignment라고 씁니다.shipmentGroupV2가 아니라. - 불가능한 상태는 표현조차 안 되게 만듭니다. 주문이 초안이면서 동시에 결제 완료일 수 없다면, 타입이 그걸 허용하지 않게 합니다. 그 규칙은 제가 외우는 대신 컴파일러가 들고 있게 두는 거죠.
- 모델은 바깥 세상을 모르게 둡니다. HTTP도, SQL도, JSON도 알 필요가 없습니다. 그것들은 모델을 감싸는 껍질이지, 그 반대가 아닙니다.
이건 형식 차리기도 아니고, 다이어그램을 위한 다이어그램도 아닙니다. 제 “모델링”은 대부분 텍스트 파일 하나와 TypeScript 타입 몇 개이고, 오후 한나절에 세 번쯤 버리고 다시 씁니다. 핵심은, 해법의 모양을 정하기 전에 문제의 모양으로 먼저 생각하는 것입니다.
요즘 흥미로운 점은, AI 에이전트가 후반부, 그러니까 스캐폴딩이나 배선, 보일러플레이트 같은 일을 정말 잘한다는 겁니다. 그래서 전반부가 덜 중요해지는 게 아니라 오히려 더 중요해집니다. 제가 넘기는 모델이 선명할수록, 돌아오는 코드도 좋습니다. 흐릿한 모델을 넘기면, 자신만만한 헛소리가 돌아옵니다.
그래서 도메인이 먼저입니다. 나머지는 다 배관 작업이고요.