많은 개발자들이 주어진 기능 명세서를 보고 바로 키보드를 두드리기 시작합니다. 하지만 정작 "왜 이 기능이 필요한가?"라는 질문은 하지 않습니다. 이런 습관이 쌓이면 단순한 코드 작성자에 머물게 되고, 진정한 문제 해결자로 성장하기 어렵습니다.
목적 없는 개발의 문제점
"이 버튼을 누르면 데이터를 서버로 전송하는 기능을 만들어주세요." 이런 요구사항을 받았을 때, 대부분의 개발자는 바로 구현에 들어갑니다. HTTP 요청을 어떻게 보낼지, 에러 처리는 어떻게 할지, 로딩 상태는 어떻게 표시할지만 고민하죠. 하지만 정작 "사용자가 왜 이 버튼을 눌러야 하는가?", "이 데이터 전송으로 사용자가 얻는 가치는 무엇인가?"는 묻지 않습니다.
이런 접근 방식의 가장 큰 문제는 맥락 없는 코드를 만든다는 것입니다. 기능은 동작하지만, 사용자의 실제 니즈와는 동떨어진 결과물이 나옵니다. 예를 들어, 단순히 "데이터 전송"만 구현했다면 전송 실패 시 사용자가 어떤 액션을 취해야 하는지, 전송 성공 후 사용자가 기대하는 다음 단계가 무엇인지 놓치게 됩니다.
또한 확장성과 유지보수성이 떨어지는 코드가 만들어집니다. 목적을 모르고 작성된 코드는 요구사항이 조금만 바뀌어도 전면 수정이 필요합니다. "데이터 전송 후 특정 조건에서는 다른 페이지로 이동해야 한다"는 요구사항이 추가되면, 처음부터 목적을 고려했다면 쉽게 확장할 수 있었을 기능도 대폭 수정해야 합니다.
더 심각한 문제는 개발자 본인의 성장이 정체된다는 점입니다. 단순히 주어진 명세를 코드로 옮기는 일만 반복하면, 문제 해결 능력이나 비즈니스 이해도가 늘지 않습니다. 시니어 개발자와 주니어 개발자의 차이는 코딩 실력이 아니라 "왜?"라는 질문을 던지고 본질적인 문제를 파악하는 능력에 있습니다. 목적을 묻지 않는 개발자는 경력이 쌓여도 여전히 주니어 수준의 사고에 머물게 됩니다.
목적 중심 개발이 만드는 차이
같은 기능이라도 목적을 이해하고 개발하면 코드의 품질이 완전히 달라집니다. 앞서 언급한 "데이터 전송 버튼" 예시로 돌아가 보겠습니다. 만약 이 기능의 진짜 목적이 "사용자가 중요한 정보를 안전하게 저장하고 싶어한다"는 것이라면, 단순한 HTTP 요청 이상의 고민이 필요합니다.
첫째, 사용자 경험이 중심이 된 코드가 만들어집니다. 목적을 아는 개발자는 전송 중 네트워크가 끊어졌을 때 데이터 손실을 방지하는 로직을 먼저 생각합니다. 로컬 스토리지에 임시 저장하거나, 재시도 메커니즘을 구현하거나, 사용자에게 명확한 상태 피드백을 제공합니다. 반면 목적을 모르는 개발자는 단순히 "전송 성공/실패" 알림만 표시하고 끝냅니다.
둘째, 확장 가능한 아키텍처가 자연스럽게 나옵니다. "안전한 저장"이라는 목적을 이해하면, 단일 API 호출보다는 검증, 전송, 확인의 단계별 처리를 고려하게 됩니다. 각 단계를 독립적인 모듈로 분리하면, 나중에 암호화 기능이 추가되거나 백업 서버 연동이 필요할 때 쉽게 확장할 수 있습니다. 처음부터 목적에 맞는 구조를 설계했기 때문입니다.
셋째, 예외 상황에 대한 고민이 깊어집니다. 목적 중심으로 생각하면 "사용자가 이 기능을 쓰다가 실패하면 어떤 기분일까?"를 자연스럽게 고민하게 됩니다. 그래서 단순한 에러 메시지 대신 "데이터가 저장되지 않았습니다. 다시 시도하시거나 고객센터에 문의해주세요"같은 actionable한 가이드를 제공합니다. 또한 부분적 실패 상황도 고려해서, 일부 데이터만 저장된 경우의 복구 방안도 미리 준비합니다.
마지막으로, 코드의 가독성과 문서화가 자연스럽게 향상됩니다. 목적을 이해한 개발자는 함수명과 변수명을 지을 때도 비즈니스 의미를 반영합니다. sendData()가 아니라 saveUserImportantInfo()처럼 명명하고, 주석도 "데이터 전송"이 아니라 "사용자 정보 안전 저장을 위한 검증 및 전송 프로세스"라고 작성합니다. 이렇게 하면 몇 달 후에 다른 개발자가 봐도, 심지어 본인이 봐도 코드의 의도를 쉽게 파악할 수 있습니다.
목적 중심 개발을 실천하는 방법
그렇다면 개발 과정에서 어떻게 목적을 찾고 유지할 수 있을까요? 이론적으로는 당연해 보이지만, 실제 개발 현장에서는 일정에 쫓기고 요구사항이 계속 바뀌면서 목적을 놓치기 쉽습니다. 다음은 바쁜 개발 일정 속에서도 목적 중심 사고를 유지할 수 있는 실전 방법들입니다.
첫째, '5Why 기법'을 개발에 적용해보세요. 요구사항을 받았을 때 최소 3번은 "왜?"를 물어보는 습관을 만드세요. "로그인 기능을 만들어주세요" → "왜 로그인이 필요한가요?" → "사용자별 개인화된 서비스를 제공하기 위해서요" → "왜 개인화가 중요한가요?" → "사용자 만족도를 높여 재방문율을 늘리려고 해요." 이런 식으로 파고들면 단순한 로그인 폼이 아니라 사용자 경험을 고려한 인증 시스템을 설계하게 됩니다.
둘째, '사용자 스토리'로 요구사항을 재정의하세요. 기술적 명세 대신 "~한 사용자가 ~하고 싶어서 ~기능을 사용한다"는 형태로 바꿔보세요. "검색 API 연동"이 아니라 "급한 정보가 필요한 사용자가 빠르게 원하는 답을 찾기 위해 검색 기능을 사용한다"로 표현하면, 검색 속도 최적화나 자동완성 같은 UX 개선 요소를 자연스럽게 고려하게 됩니다.
셋째, 정기적인 '목적 점검' 시간을 가지세요. 스프린트 중간이나 기능 개발이 80% 완료된 시점에서 "이 코드가 정말 사용자 문제를 해결하고 있나?"를 점검해보세요. 실제로는 예상보다 더 자주 목적에서 벗어난 구현을 하고 있음을 발견할 것입니다. 이때 코드를 완전히 뒤엎을 필요는 없고, 핵심 부분만 목적에 맞게 조정하면 됩니다.
넷째, 동료와의 '목적 공유'를 습관화하세요. 코드 리뷰할 때 구현 방법뿐만 아니라 "이 기능의 목적이 무엇인지" 설명하는 시간을 가지세요. 설명하다 보면 본인도 목적을 더 명확히 이해하게 되고, 동료들도 다양한 관점에서 피드백을 줄 수 있습니다. "이 방법도 같은 목적을 달성할 수 있지 않나요?"라는 질문을 통해 더 나은 해결책을 찾을 수도 있습니다.
마지막으로, '실패 시나리오'를 미리 그려보세요. 만든 기능이 사용자에게 실망을 줄 수 있는 상황들을 구체적으로 상상해보세요. 로딩이 오래 걸린다면? 에러가 발생한다면? 데이터가 없다면? 이런 상황에서도 원래 목적을 달성할 수 있는 대안을 미리 준비해두면, 더 견고하고 사용자 친화적인 코드를 작성할 수 있습니다.
코딩은 단순히 명령을 컴퓨터 언어로 번역하는 작업이 아닙니다. 사용자의 문제를 이해하고, 그 문제를 해결하는 가장 적절한 방법을 코드로 구현하는 창조적 행위입니다. "왜 만드는가?"라는 질문을 통해 더 나은 개발자로 성장하고, 진정으로 가치 있는 소프트웨어를 만들어나가시기 바랍니다.