개발회사가 쓰는 IT·개발 이야기

좋은 개발은 개발사 혼자 만들지 않는다

2026년 6월 21일 · 조회 7

변경 비용은 왜 차이가 날까? 소프트웨어의 본질은 복잡도이고, 설계란 그 복잡도를 어디에 둘지 정하는 일이다. 엉망인데 성공한 스타트업과 설계만 하다 실패한 대기업이라는 반례, 언제 단순하게·언제 재설계할지의 기준, 그 복잡도를 모듈에 가두는 우리의 실제 방식, 그리고 결국 소통까지 — 수백 개의 프로젝트를 만들고 운영하며 든 생각.

프로젝트가 실패하는 이유는, 의외로 기술이 아닌 경우가 많습니다. 코드를 잘못 짜서가 아니라 무엇을 어떻게 만들지를 끝까지 정하지 못해서 어그러지는 쪽이 훨씬 많더군요.

수백 개의 프로젝트를 만들고 운영하다 보면 비슷한 장면이 반복됩니다. 일단 만들고, 써보니 어긋나고, 고치고, 고치니 또 깨지고… 그래서 "기획과 설계에 먼저 시간을 써야 한다"고 자주 말하게 됩니다. 대체로 맞습니다. 하지만 거기서 멈추면 절반만 본 것 같더군요. 한 단계 더 들어가 봅니다.

미리 말씀드리면, 아래는 어느 것도 "이게 정답"이라는 이야기가 아닙니다. 여러 프로젝트를 거치며 저희가 도달한 저희 나름의 생각일 뿐이고, 상황에 따라 얼마든지 다를 수 있습니다.

왜 어떤 변경은 한 줄이고, 어떤 변경은 전부를 흔드나

"변경 비용이 크니까 설계가 중요하다"까지는 누구나 압니다. 진짜 질문은 그다음입니다. 왜 어떤 변경은 싸고, 어떤 변경은 비싼가?

제 결론은 이렇습니다. 소프트웨어의 본질은 결국 복잡도이고, 복잡도는 없앨 수 없습니다. 옮길 수 있을 뿐입니다. 그렇다면 설계란 기능을 만드는 행위가 아니라, 그 복잡도를 어디에 둘지 결정하는 행위입니다.

잘 배치된 복잡도는 변경이 한 곳에 모입니다. 잘못 배치된 복잡도는 작은 변경 하나가 여기저기로 번집니다. "결제 API 호출하고 DB에 저장"이 나중에 비싼 이유는, 결제라는 도메인의 복잡함(상태·정책·환불·정산)을 코드 곳곳에 흩뿌렸기 때문입니다. 반대로 도메인을 나누고 상태를 한곳에서 관리하면, 그 복잡도가 한 군데 갇힙니다. 좋은 설계란 결국, 미래의 변경이 '한 곳'에서 일어나도록 복잡도를 배치해 두는 일입니다.

그래서 작동만 되는 코드가 위험한 건 느려서가 아니라, 복잡도를 아무 데나 두었기 때문입니다. 그 위에 얹을수록 변경이 사방으로 번지고, 결국 손대기 무서워져 "갈아엎자"가 됩니다. 마이그레이션 비용은, 미뤄둔 복잡도 정리 비용을 한꺼번에 치르는 것에 가깝습니다.

개발을 안 해보신 분께는 이렇게 설명드립니다. 다 지은 집에서 벽 위치를 바꾸는 일과 비슷합니다. 도면 단계에서 벽을 옮기는 건 지우개질 한 번이지만, 골조가 다 올라간 뒤엔 배관·전기·하중까지 같이 손봐야 합니다. 요구사항이 뒤늦게 바뀔수록 비용이 커지는 건, 개발자가 일을 키워서가 아니라 구조가 원래 그렇게 생겼기 때문입니다. 그래서 "무엇을 만들지"를 앞에서 충분히 맞춰두는 게, 결국 가장 싼 방법인 경우가 많습니다.

사용자는 기능이 아니라 흐름을 경험한다

개발자는 로그인·결제를 각각의 기능으로 보지만, 사용자는 "회원가입 → 탐색 → 구매 → 환불"이라는 하나의 흐름으로 경험합니다. 따로따로는 잘 도는데 이어 붙이면 어긋나는 건, 이 흐름을 먼저 그려보지 않았기 때문입니다. 흐름을 설계한다는 건, 기능 사이의 복잡도(연결·상태 전이)를 미리 배치한다는 뜻이기도 합니다.

그런데 — 반례들

여기까지면 "그러니 설계하라"로 끝날 텐데, 정직하려면 반례를 봐야 합니다.

왜 어떤 스타트업은 엉망으로 짰는데도 성공했을까? 초기엔 코드 품질보다 "시장이 이걸 원하는가"가 압도적으로 중요하기 때문입니다. 방향이 틀렸거나 곧 갈아엎을 코드라면, 거기 들인 설계는 그냥 낭비입니다. 복잡도 관리의 복리는 오래 살아남아 자주 바뀌는 코드에서만 작동합니다. 살아남지 못할 코드엔 이자가 붙지 않습니다.

왜 어떤 대기업은 설계를 몇 달 했는데도 실패했을까? 설계의 '양'이 아니라 '방향'이 문제였기 때문입니다. 현실의 사용자·변경과 동떨어진 설계는, 잘못된 곳에 복잡도를 가둡니다. 오지 않을 미래를 위해 복잡도를 미리 사두는 것 — 사용자 100명짜리 서비스에 MSA·CQRS·Kafka·분산 트랜잭션을 까는 것 — 이게 과도한 설계(over-engineering)입니다.

그래서 진짜 기준은 "설계를 하느냐 마느냐"가 아닙니다. 이 소프트웨어가 오래 살고 자주 바뀔 것인가. 그 답에 따라 설계에 쓸 양이 정해집니다. 성공한 스타트업도 "설계 없이"가 아니라 "최소한의 설계 + 빠른 검증"을 한 겁니다. 핵심 흐름만 설계하고, MVP로 검증하고, 검증된 부분만 고도화하는 순서로요.

그렇다면, 언제 단순하게 두고 언제 재설계하나

"균형이 중요하다"는 말은 사실 아무 말도 아닙니다. 균형을 어떻게 판단하느냐가 핵심이죠. 제가 쓰는 신호들은 이렇습니다.

균형은 감이 아니라, 이런 신호로 판단할 수 있습니다.

그래서 우리는 — 복잡도를 '모듈'에 가둔다

여기까지가 추상론처럼 들릴 수 있어, 저희가 실제로 일하는 방식을 잠깐 적어봅니다. 결제, 소셜 로그인, 실시간 채팅, 알림, SEO… 결이 다른 서비스를 만들어도 거의 매번 다시 마주치는 복잡도가 있습니다. 저희는 이걸 프로젝트마다 새로 풀지 않습니다. 한 번 제대로 설계한 공통 모듈(저흰 ld-* 라고 부릅니다)에 그 복잡도를 가둬두고, 새 서비스는 그걸 가져다 씁니다.

어쩌면 이건 회사의 성격 차이일지도 모릅니다. 한 가지 제품을 깊게 파는 회사라면 모듈보다 그 제품 자체에 더 집중하는 게 맞을 겁니다. 하지만 외주나 SI처럼 성격이 다른 프로젝트를 여럿 만들고 운영하는 회사라면, 매번 맨손으로 짓기보다 잘 만든 부품을 갖춰 두고 조립 라인처럼 찍어내는 '공장'다운 면모를 갖추는 쪽이 훨씬 능률적이지 않나 싶습니다. 같은 걸 두 번 만들지 않는 것 — 그게 결국 효율이자 속도더라고요. 그래서 저희는 모듈이야말로 저희 같은 외주·SI·개발대행 회사가 길게 봐야 할 방향이라고 생각합니다. 일반 소프트웨어 회사가 한 제품의 완성도에 승부를 건다면, 여러 프로젝트를 다루는 회사의 승부처는 결국 '같은 일을 얼마나 안 반복하느냐'에 있다고 보거든요.

핵심은 무엇을 모듈에 두고 무엇을 두지 않느냐입니다. 모두가 똑같이 마주치는 복잡한 부분 — 결제의 환불·정산, 로그인의 인증 흐름, 메시지의 순서 보장 같은 것 — 만 모듈이 떠안고, 서비스마다 다른 부분은 각 서비스가 따로 갖습니다. 이 경계만 잘 그어두면, 결제 정책이 바뀌어도 한 곳만 손대면 되고, 한 서비스의 화면이 바뀌어도 그 서비스만 바뀝니다. 변경이 사방으로 번지지 않습니다 — 앞에서 말한 "변경이 한 곳에서 일어나게"를, 모듈 경계로 실현한 셈입니다.

솔직히 공통 모듈은 어렵습니다. "재사용은 생각보다 어렵고, 복사는 생각보다 싸다"는 말이 괜히 있는 게 아닙니다. 처음엔 생산성이 폭발하다가, 어느 순간 모든 서비스가 그 하나에 묶여 한 곳을 고치면 여기저기가 같이 터지고, 호환성·배포·버전 관리 비용이 쌓여 흔히 말하는 '버전 지옥'이 됩니다. 그래서 공통화는 성공보다 실패가 더 흔하고, 큰 회사들조차 섣불리 묶기보다 서비스 독립을 택하는 경우가 많습니다. 모듈화는 공짜도, 아무나 되는 일도 아닙니다.

그런데 저희는 바로 그 점이 핵심이라고 봅니다 — 어려우니까, 해내면 그게 곧 차별점이 됩니다. 그 '버전 지옥'은 모듈화의 숙명이라기보다 모듈을 그 수준으로밖에 못 만들었을 때 생기는 일에 가깝고, 충분히 높은 수준으로 만들어 꾸준히 관리할 역량이 있다면 관리 비용을 치르고도 재사용 이득이 더 커지는 지점이 옵니다 — 모듈이 늘수록 짐이 아니라 무기가 되는 지점이요. 그래서 정리하면 이렇습니다. 같은 일이 계속 반복되고 그걸 꾸준히 다듬어 갈 수 있는 회사(외주·SI·개발대행이 대표적입니다)라면, 모듈은 가야 할 길입니다. 반대로 한 제품에 집중하는 회사라면 굳이 이 길일 필요가 없습니다 — 프로젝트 간 재사용 이득이 적어 차라리 복사가 합리적일 때가 많고, 역량과 여력이 없는데 무리하면 그대로 버전 지옥이니까요. 즉 "좋은 개발 = 모듈화"라는 보편 정답이 아니라, 그게 무기가 되는 회사가 따로 있는 선택입니다. 저희는 그 무기가 되는 쪽에 서기로 했고, 그래서 오래 투자해 왔습니다.

그렇게 만든 모듈은 한번 짜두면 못 바꾸는 '딱딱한' 부품이 아니라, 레고처럼 끼웠다 빼는 조립형에 가깝습니다. 새 서비스는 필요한 모듈만 골라 끼우고, 나머지는 아예 안 써도 됩니다 — 게시판이 필요 없으면 안 가져오면 그만입니다. 서로 거의 기대지 않게 만들어 두어서, 모듈이 스무 개 서른 개로 늘어도 한 덩어리가 되지 않고 각자 독립적으로 굴러갑니다.

이게 잘 쌓이면 힘은 생각보다 큽니다. 결제·로그인·채팅·알림·SEO처럼 이미 풀어둔 복잡도를 그대로 끼워 넣고, 정작 그 서비스만의 핵심에만 집중하면 되니까요. 저희가 사주풀이·발렛 예약·1인 기업 도구·주식 분석처럼 성격이 전혀 다른 서비스를 짧은 주기로 만들어 올 수 있었던 건, 특별히 빨라서가 아니라 같은 복잡도를 매번 새로 풀지 않기 때문입니다. — 물론 이것도 정답이라기보다, 저희가 여러 프로젝트를 거치며 도달한 저희 나름의 생각입니다.

사실 이 글이 올라온 콕컷도 같은 원리로 만들었습니다. '글'과 'SEO'라는 복잡도를 모듈로 떼어내 두었고, 다음 서비스에서 또 씁니다. 좋은 개발은 결국, 한 번 잘 풀어둔 복잡도를 두 번 풀지 않는 일이기도 합니다.

그래서, 결국은 소통이다 — 그런데 소통은 왜 어려운가

이 모든 판단은 결국 소통 위에서 이뤄집니다. 그런데 소통이 어려운 이유는 분명합니다. 각자 보는 게 다르고, 같은 단어로 다른 걸 말하기 때문입니다. 발주자는 문제를, 개발자는 구현을, 디자이너는 사용자를 봅니다. "간단한 거잖아요"와 "그게 안 간단해요"는 사실 서로 다른 세계를 말하는 중입니다.

좋은 소통은 분위기가 좋은 게 아니라, 역할별 책임이 분명한 것이더군요.

물론 발주자가 자기 문제를 처음부터 또렷이 아는 경우는 생각보다 드뭅니다. 그래서 "발주자가 문제를 정의해야 한다"기보다, 개발사가 함께 질문하며 진짜 문제를 찾아내는 것까지가 일이라고 봅니다. 좋은 개발사는 시키는 걸 받아 적기만 하지 않고, "정말 풀어야 할 게 이건가요?"를 같이 되묻는 쪽에 가깝더군요. 그러니 이건 발주자에게 책임을 미루는 이야기가 아니라, 문제를 같이 발견하자는 이야기에 가깝습니다.

그래서 개발을 맡기시는 분께 — '개발'을 '코딩'으로만 보지 않으셨으면 합니다. 무언가를 만든다는 건 문제를 정의하고 → 흐름을 설계하고 → 만들고 → 검증하고 → 고쳐나가는 과정 전체입니다. 발주자가 이 과정을 이해하고 자기 책임(문제를 또렷이 설명하는 것)을 다할 때, 비로소 위의 모든 판단이 제대로 작동합니다. 좋은 결과물은 잘 만드는 개발사가 혼자 만드는 게 아니라, 그 과정을 함께 이해하는 발주자와 같이 만드는 것에 가깝습니다.

정리하며

최악은 둘입니다. 생각 없이 일단 코딩하는 것, 그리고 완벽한 설계를 기다리다 끝내 시작하지 못하는 것. 그 사이 어디쯤에서, 복잡도를 어디에 둘지 / 언제 움직일지 / 누가 무엇을 말할지를 매번 판단하는 일 — 그 판단의 합이 결국 좋은 개발인 것 같습니다.

정답표는 없습니다. 하지만 신호와 기준은 있고, 무엇보다 그걸 혼자 읽어낼 필요가 없습니다. 발주자와 개발사가 같은 그림을 보고 함께 판단할 때, 결과가 달라집니다.

좋은 개발은, 결국 개발사 혼자 만드는 것이 아니었습니다.


로동은 많은 프로젝트를 만들고 운영하며, 이렇게 '함께' 만드는 걸 고민합니다. — lodong.co.kr

도움이 됐다면 추천해주세요

댓글 0