What Defines a Day?
프로그래머들은 새로운 기능을 만들 때 종종 잘못된 것에 집중하곤 합니다.
백엔드 데이터, 코드 중복, 또는 성능을 생각할 수도 있습니다. 이러한 질문들도 중요합니다. 하지만 가장 중요한 질문은 아닙니다.
저도 종종 이런 실수를 합니다. 스마트한 패턴과 깔끔한 코드에 매료되곤 하죠. 사용자가 기능을 어떻게 사용하는지 완전히 이해하기도 전에 코딩을 시작합니다. 그러다 보면 제 코드가 비즈니스 목표와 일치하지 않는다는 사실을 깨닫게 됩니다.
캘린더 앱을 예로 들어보겠습니다.
사용자가 공휴일을 표시하기 위해 3월 1일을 클릭합니다. 하지만 앱은 대신 2월 28일을 표시합니다. 이는 타임존(timezone) 때문에 발생합니다.
개발자는 Date 객체를 사용했습니다. Date 객체는 특정 시점의 순간을 나타냅니다.
도쿄의 3월 1일 자정은 런던에서는 여전히 2월 28일입니다. 만약 코드가 날짜를 저장하기 위해 UTC 메서드를 사용한다면, 날짜가 어긋나게 됩니다.
이 버그는 기술적 구현이 비즈니스 로직과 충돌하기 때문에 발생합니다.
사용자는 날짜 단위로 생각합니다. 사용자는 UTC 오프셋이나 밀리초 타임스탬프로 생각하지 않습니다. 그들은 "3월 14일을 원해"라고 생각합니다.
코드가 신뢰할 수 있기를 원한다면, 도메인을 올바르게 모델링해야 합니다.
종이 달력에서 날짜는 그저 연, 월, 일일 뿐입니다. 타임존이 없습니다.
UTC나 로컬 시간과 일관성을 유지함으로써 버그를 수정할 수도 있습니다. 하지만 그것은 임시방편일 뿐입니다. 더 나은 방법은 오류가 발생할 수 없는 데이터 구조를 사용하는 것입니다.
Date 객체 대신 커스텀 객체를 사용하세요:
• 연도: 2026 • 월: 3월 • 일: 1
이렇게 하면 고려 대상에서 시간과 타임존을 제외할 수 있습니다. 버그가 발생하는 것을 원천적으로 차단합니다.
네, 이 방식은 더 많은 노력이 필요합니다. 날짜를 비교하거나 월말을 찾는 유틸리티를 직접 작성해야 합니다. 마감 기한과 스프린트도 신경 써야 하죠.
하지만 도메인을 올바르게 모델링하면 나중에 쏟아지는 항의성 고객 지원 티켓과 몇 시간씩 걸리는 디버깅으로부터 당신을 구해줄 것입니다.
에릭 에반스(Eric Evans)가 《도메인 주도 설계(Domain-Driven Design)》에서 말했듯이:
"효과적으로 소통하기 위해서, 코드는 요구사항을 작성할 때 사용된 것과 동일한 언어를 기반으로 해야 한다."
프로그래머로서만 생각하는 것을 멈추세요. 비즈니스 규칙에 대해 생각하기 시작하세요.
