소프트웨어 개발자분들의 블로그를 보면, 또는 회사 기술블로그들을 봐도, 기술부채라는 용어를 가끔씩 볼 수 있습니다. 그런데, 가만히 보면 원래의 뜻과는 다른 의미로 사용되는 경우가 많아보입니다. 물론 용어와 개념은 원래의 뜻대로만 유지되어야 하는 것은 아니고 시대에 따라서 변천되기도 하지만, 원래의 의미는 무엇이었는지를 모른채 새로운 의미로 사용하는 것과, 알지만 그 의미를 확장해서 사용하는 것은 다르다는 생각에, 기술부채라는 용어의 역사와 그 원래 의미에 대해서 글을 써봅니다.

위키의 아버지, 워드 커닝햄

기술부채(Technical Debt)라는 표현을 만든 사람은 누구일까요? 워드 커닝햄(Ward Cunningham)입니다. 모르는 분들이 많을텐데요, ‘위키위키의 아버지’라고 하는 것이 그나마 가장 많은 분들이 들어봄직한 업적일 것 같습니다. 위키피디아에 의하면, 1995년에 첫번째의 위키가 세상에 등장했습니다.

그러면 이 첫 번째의 위키에는 어떤 내용을 담았냐, 무엇을 위해서 만들었냐. 흥미롭게도, 이 위키의 이름은 포틀랜드 패턴 저장소(Portland Pattern Repository)입니다. 많은 소프트웨어 개발자분들이 들어보거나 알고 있는, ‘디자인 패턴’이라고 할 때의 그 패턴입니다.

크리스토퍼 알렉산더라는 건축가이자 이론가가 ‘영원의 건축(The Timeless Way of Building)’, ‘패턴 랭귀지(A Pattern Language)’라는 책들을 발간하면서, 소프트웨어 개발 업계의 사람들은 빠른 속도로, 적극적으로 그 아이디어를 받아들였습니다. 그리고 그 결과를 ACM의 한 분과 중 하나인 OOPSLA(Object-Oriented Programming, Systems, Languages & Applications) 컨퍼런스, 그리고 PLoP(Pattern Languages of Programs) 컨퍼런스에서 발표하고 공유하고 논의하곤 했습니다.

‘오리지널 위키(original wiki)’라고 부르기도 하는 이 첫 번째의 위키에는, 소프트웨어 개발 분야의 사람들이 모여서 패턴 언어를 적용하기 위한 의견을 교환하고, 고안된 패턴들을 기록하는 용도로 사용되었습니다.

“Technical Debt”, 세상에 나오다

워드 커닝햄은 OOPSLA 92에서 “The WyCash Portfolio Management System”이라는 주제로 발표를 합니다.

OOLSPA 92 발표 자료 (번역)

The WyCash Portfolio Management System

미국의 연금 기금, 기업 및 은행들은 "현금" 시장에 수십억 달러를 투자하고 있습니다. 현금 증권은 일반적으로 잔여 만기가 1년 미만인 증권을 의미하지만, 최대 5년까지 만기인 증권도 포함될 수 있습니다. 매우 다양한 성격을 가진 현금 증권은 실제로 발행자와 구매자 간에 협상에 의해 결정되며, 새로운 증권 유형이 자주 시장에 도입됩니다. WyCASH+는 현금 포트폴리오 관리자를 지원하기 위해 기본 회계, 기록 유지 및 보고서 작성뿐만 아니라 분석 계산 기능을 제공하는 포트폴리오 관리 시스템입니다.

WyCASH+의 개발을 위해 Wyatt Software는 시장의 다양성에 신속하고 효과적으로 대응하기 위해 객체 기술을 활용하기로 결정했습니다. 객체는 두 가지 방법으로 도움이 됩니다. 첫 번째로, 많은 증권 유형이 우리의 언어(Smalltalk)에서 직접 지원하는 상속 계층에 잘 맞춰지기 때문에 상당한 코딩 노력을 절약할 수 있습니다. 두 번째로, 변화하는 시장 수요는 종종 대규모 수정을 요구하지만, 완전한 객체 지향 구현에 내재된 모듈성 덕분에 우리는 이를 수용할 수 있었습니다. 우리의 고객들은 우리의 반응성을 현재 필요에 대한 제품의 적합성만큼, 아니 그 이상으로 중요하게 여깁니다.

우리는 작동하는 프로토타입에서 점진적으로 성장하는 방식으로 제품을 개발했습니다. 우리의 소규모 엔지니어링 팀의 각 구성원은 대략 4MB의 소스 코드의 모든 측면에 대한 일반적인 지식을 유지하고 있습니다. 여기에는 공급업체가 제공한 일부 라이브러리와 제3자 계약자가 당사의 사양에 맞춰 작성한 다른 라이브러리가 포함됩니다. 프로그램의 성숙한 부분은 여러 번 수정되거나 재작성되어, 이해와 지속적인 점진적 개발의 핵심인 응집(consolidate)을 제공합니다.

우리는 이 과정이 가장 적절한 제품을 가능한 한 짧은 시간에 만들 수 있다고 믿습니다. 그러나 함정이 있습니다. 모든 사람이 갑작스러운 방향 변화에 편안함을 느끼는 것은 아니며, 특히 프로그래머들은 더욱 그러합니다. 여기서 최선의 해독제는 제품과 그 구현에 대한 더 완전한 친숙함입니다. 변화는 실행 가능하다고 인식될 때 수용됩니다.

다른 더 심각한 위험 요소는 통합 실패입니다. 비완전한(immature) 코드가 잘 작동하고 고객에게 완전히 수용 가능할 수 있지만, 과도한 양은 프로그램을 마스터하기 어렵게 만들어 프로그래머의 극단적인 전문화를 유도하고 결국 비유연한(inflexible) 제품을 초래할 수 있습니다. 처음 작성한 코드를 출시하는 것은 마치 채무(debt)를 지는 것과 같습니다. 작은 부채(debt)는 신속히 갚는다면 개발 속도를 높일 수 있습니다. 객체는 이 거래 비용을 감당할 수 있게 만듭니다. 그러나 부채(debt)가 상환되지 않을 때 위험이 발생합니다. 완벽하지 않은 코드에 소비한 모든 시간은 그 부채(debt)에 대한 이자로 계산됩니다. 비통합적인 구현의 부채 부담 때문에 전체 엔지니어링 조직이 정체될 수 있습니다. 이는 객체 지향적이든 아니든 마찬가지입니다.

Wyatt Software가 객체 기술을 계속 사용할 것이라는 점에는 의심의 여지가 없습니다. 선도적인 객체 지향 언어에 대한 깊은 지식이 있는 우리는, 그들의 이점을 어떻게 잘 활용할지를 결정하는 것만 남았습니다. 전통적인 폭포수 개발 주기는 프로그래밍이 시작되기 전에 프로그램을 세부적으로 설계하여 프로그래밍 재앙을 피하려고 노력해왔습니다. 우리는 커뮤니티가 이러한 기술을 객체에 적용하려고 시도하는 것을 흥미롭게 지켜보고 있습니다. 그러나 우리 부채(debt) 비유를 사용하자면, 이는 선불 및 전액 지급(전액 선불, up-front and in-full)의 개념을 유지하는 것과 같다고 인식(recognize)합니다. 객체가 제공하는 모듈성과 응집(consolidate)의 실천은 경쟁이 치열한 금융 소프트웨어 시장에서 대안으로서 점진적 성장을 실현 가능하고 바람직하게 (하지만 항상 편안하게는 아님) 만듭니다.

이 시스템은 현금 증권 포트폴리오 관리 시스템으로, 스몰토크(Smalltalk) 언어를 기반으로 개발되었습니다. 당시에는 새로운 기술이었던 객체지향 기술을 사용했고, 새로운 증권 유형이 자주 시장에 도입되는 등, 시장의 새로운 요구에 유연하게 대응해야 할 필요가 있었습니다. 이러한 새로운 개발 전략을, 익숙치 않은 사람들에게 설명하기 위해서, 워드는 마침 개발하고 있던 재무 시스템 분야의 표현을 빌려서, “부채”라는 은유를 사용합니다.

Technical Debt

기술 부채에 대한 왜곡된 이해들이 퍼져나가자, 2009년에 워드는 기술 부채라는 은유를 어떤 배경에서 만들었는지를 설명하는 동영상도 올렸습니다. 정리된 녹취록도 오리지널 위키에 정리되어 있습니다.

Debt Metaphor (번역)

Debt Metaphor

은유

조지 레이코프와 마크 존슨의 Metaphor We Live By를 읽은 후, 은유가 우리의 사고 방식을 어떻게 영향을 미치는지에 관심을 가지게 되었습니다. 중요한 아이디어는 우리가 언어에 들어온 은유로 비유를 통해 추론한다는 것입니다.

부채

WyCash 제품의 리팩토링을 설명하기 위해 부채(debt) 은유를 만들었습니다. 이 제품은 Digitalk Smalltalk로 개발된 초기 제품이었으며, 시간이 지남에 따라 애플리케이션에 대한 학습을 축적하기 위해 프로그램을 수정하여 마치 처음부터 제대로 알고 있었던 것처럼, 그리고 Smalltalk에서 쉽게 할 수 있었던 것처럼 보이게 하는 것이 중요했습니다. 제가 상사에게 한 설명은 재무 소프트웨어에 대한 재무적 비유인 "부채 은유"였습니다. 이는 우리가 재무 객체에 대해 이해하는 바에 맞게 프로그램을 정렬하지 못한다면, 우리는 끊임없이 그 불일치에 걸려 넘어질 것이고 이는 마치 대출의 이자를 지불하는 것과 같다는 의미였습니다.

속도

빌린 돈으로 본래보다 더 빨리 일을 진행할 수 있지만, 그 돈을 갚기 전까지는 이자를 지불해야 합니다. 저는 돈을 빌리는 것이 좋은 생각이라고 생각했고, 소프트웨어를 재빨리 출시하여 경험을 쌓는 것도 좋은 아이디어라고 생각했습니다. 하지만 또한, 결국 소프트웨어에 대해 배우면서 그 대출을 상환하기 위해 프로그램을 리팩토링할 것이라는 점도 알고 있었습니다.

부담

사람들이 소프트웨어를 서둘러(rush) 출시하고 배움들을 얻지만, 그렇게 배운 부분 들을 프로그램에 다시 반영하지 않는 사례가 많았던 것 같습니다. 이는 부채를 빌리고 갚을 필요가 없다고 생각하는 것과 유사합니다. 물론, 만약 당신이 그렇다면, 예를 들어 신용카드를 사용하게 되면 결국 모든 소득이 이자로 가고 구매력은 제로가 됩니다. 마찬가지로, 오랜 시간 동안 기능만 추가하며 프로그램을 개발하고, 그 기능에 대한 이해를 반영하여 재조직(reorganizing)하지 않는다면, 결국 그 프로그램은 아무런 이해를 담고 있지 않게 되어 모든 작업 노력들이 점점 더 오래 걸리게 됩니다. 즉, 이자는 총체적입니다 -- 당신은 전혀 진전을 이루지 못할 것입니다.

민첩성

많은 블로거들이 적어도 부채 은유를 설명했지만, 제 생각에는 그들이 제 생각을 잘못 이해한 것 같습니다. 즉, 나중에 좋은 작업을 할 생각을 가지고 나쁜 코드를 작성해도 된다고 말한 것으로 (잘못) 이해한 것 같습니다. 그리고 그것이 부채의 주요 원인이라고 여기는 것 같습니다.

나는 나쁜 코드를 작성하는 것에 찬성하지 않지만, 현재 문제에 대한 이해를 반영하는 코드를 작성하는 것에는 지지합니다. 비록 그 이해가 불완전하더라도 말입니다.

잘 아시겠지만, 당신이 완전히 이해하지 못한 상태에서 그런 방식으로 부채를 지고 싶다면, 가능한 한 당신의 이해를 잘 반영하도록 그 소프트웨어를 개발하는 것이 현명합니다. 그렇게 하면 리팩토링할 시점이 되었을 때, 당신이 그것을 썼을 때 어떤 생각을 했는지가 명확해져 현재의 이해를 기반으로 리팩토링하기가 쉬워집니다.

즉, 부채 은유, 즉 부채를 갚을 수 있는 능력과 부채 은유가 당신에게 유리하게 작용하도록 하는 것은, 문제를 이해하게 되면서 언제든지 리팩토링할 수 있을 만큼 충분히 깔끔한 코드를 작성하는 데 달려 있습니다.

나는 이것이 좋은 방법론이라고 생각합니다. 이는 ExtremeProgramming의 핵심에 있습니다. 부채 은유는 ExtremeProgramming이 작동하는 이유를 설명하는 여러 가지 설명 중 하나입니다.

대개 기술 부채에 대한 글에서, “빨리 개발하느라 기술적 완성도를 희생하는 것”, “그건 빚처럼 위험한 것이고, 필요악 같은 것이라서 빨리 갚아야 한다”라고 설명하는 경우가 많이 보입니다. 워드도 이에 대해 알고 있는 것 같고, 그것이 기술부채를 오해-잘못 이해한 것이라고 이야기합니다.

많은 블로거들이 적어도 부채 은유를 설명했지만, 제 생각에는 그들이 제 생각을 잘못 이해한 것 같습니다. 즉, 나중에 좋은 작업을 할 생각을 가지고 나쁜 코드를 작성해도 된다고 말한 것으로 (잘못) 이해한 것 같습니다. 그리고 그것이 부채의 주요 원인이라고 여기는 것 같습니다.

A lot of bloggers at least have explained the debt metaphor and confused it, I think, with the idea that you could write code poorly with the intention of doing a good job later and thinking that that was the primary source of debt.

기술 부채의 온전한 의미

그러면 기술 부채의 온전한 의미는 무엇일까요? 앞서 워드 커닝햄이 기술 부채에 대해 설명한 두 개의 글을 소개해드렸는데, 그에 기반해서 이해해봅시다.

그리고 또 애자일의 눈으로 기술부채를 바라봐야 이해할 수 있기도 합니다. 워드 커닝햄은 켄트 벡, 론 제프리스 등과 더불어 익스트림 프로그래밍이라는 애자일 방법론 중 하나를 만든 사람이고, 애자일 선언문에 서명한 17명 중 한 명이기도 하거든요.

기술 부채는 단기적인 성과를 위해 장기적인 품질을 희생하는 것이 아닙니다. 기술 부채의 원래 의미는 지식의 축적과 시장 변화에 따른 전략적 선택으로 해석될 수 있습니다. 워드 커닝햄이 제시한 비유를 다시 요약해서 보면 이렇습니다. 소프트웨어 개발에 대한 불확실성을 감안할 때, 개발팀은 필연적으로 “부채”를 지면서도 빠르게 시장의 요구에 적응할 필요가 있습니다. 결국, 기술 부채는 우리가 경험하고 배우는 과정에서 발생하는 필연적인 도구이며, 이 학습의 기회를 통해 최종적으로 더 나은 제품을 만들어낼 수 있습니다.

비즈니스를 전개해 나가다 보면, 특히 스타트업의 경우 불확실성이 높습니다. 우리는 사용자가 원하는 것이 무엇인지 또는 비즈니스 모델이 어떻게 전개될지를 알기 어렵습니다. 이러한 불확실한 상황에서 우선 대출을 받아서 현재 수준에서 아는 바를 기반으로 개발하는 것이 필요합니다. 시간이 지남에 따라 우리는 고객 피드백과 시장의 반응을 통해 배운 것들을 축적하고, 그 경험을 바탕으로, 과거에 불명확한 정보를 통해 작성한 코드와 설계를 점진적으로 개선해 나갈 수 있습니다. 이는 해결책을 즉각적으로 찾거나, 스펙을 당장 명확하고 포괄적으로 작성해서 개발하기보다, 지속적인 개선을 통해 궁극적으로 더 높은 품질의 소프트웨어를 만들어 가는 접근 방식입니다.

뭐랄까요. ‘내가 장사를 하려면, 장사에 대한 학원도 다니고, 공부도 엄청 하고, 완전히 빠삭하게 알아야만 시작할 수 있어. 안그러면 실패하기 십상이야. 완전히 알고 있는 상태에서 시작할거야.’라는 마인드와, ‘완전히 아는게 어떻게 가능해? 그랬다가는 시간만 흐르게 될거야. 그리고, 학원 다니고 공부를 한들, 그 사이에 시간이 흘러서 그때 배운 지식들은 오래되어 쓸모없는게 될 수도 있지. 일단 지금 수준에서 시작을 해보고, 차차 감을 잡아가면서 보완해나가자.’라는 마인드의 차이랄까요?

워드가 OOPSLA 92에서 발표한 ‘WyCash’ 사례에서 언급한 것처럼, 기술 부채를 통한 개발이 항상 쉬운 것은 아닙니다. 코드나 설계가 지저분해지고 복잡해지기 쉽습니다. 그리고 확실성을 중요시하는 개발자는 이러한 접근 방식에 불편함을 느낄 수 있습니다. 주기적인 코드 리뷰와 리팩토링 기회를 통해서 계속 갱신되는 비즈니스에 대한 지식을 코드와 설계에 반영하면서, 기술 부채를 단순히 방치하지 않고 지속적으로 갚는 노력을 기울여야 합니다.

그런 점에서 기술 부채를 다시 재정의하자면, “당장의 개발 속도를 위해서 코드 품질을 희생하는 것, 그리고 나중에는 설계나 코드, 테스트 등, 빼먹은 것을 꼭 제대로 충원해야만 하는, 안그러면 큰일 나는 것”이 아니라, “모든 것을 완벽하게 알 수 없는, 또는 현재 시점에서는 확실했더라도, 또 시장이나 법규, 제도, 사용자의 니즈 등이 변화하면서, 근본적으로 변화할 수 밖에 없는 그러한 상황에서, 현재 확실한, 상대적으로 적은 정보에 기대어 최선을 다해 개발하고, 그것을 토대로 시스템을 운영해나가면서, 알게 된 것들을 바탕으로, 그때 알았던 것과 지금 알고 있는, 알게 된 것 사이의 차이(gap)를 지속적으로 코드와 설계에 반영하며 메우면서 개발을 진행해가는 것”이라고 말할 수 있겠습니다.

일상의 개발에 적용할만한 팁

기술 부채에 대한 이러한 이해는, 주니어 개발자 분들에게도 좋은 격언이 될 수 있습니다.

10년이 넘는 시간 동안 개발팀장, CTO를 하며 여러 주니어분들을 접한 경험을 떠올려봤을 때, 종종 보게 되는 장면은,

  • 처음부터 너무 많은 것들을 상상해서 생각합니다. ‘이런 경우도 있겠지, 저런 경우도 대비해야겠어’. 과도하게 ‘나중에 필요할법한 것’까지 미리 감안하여 잔뜩 힘이 들어간 과도한 설계를 하고 힘들어하며 구현하는 경우를 많이 봅니다.
  • 하지만 또 정작 중요한 것은 고려하지 못하기도 합니다. 그렇게 거창하게 만든 코드나 설계는, 예상치를 벗어난 추가 요구사항을 만나면 너무나 쉽게 부서지기도 합니다. 새 옵션을 넣기 위해서 설계를 많이 깨뜨려야 한다던지요.
  • 사업이 전개되어 가는 과정에서, ‘결국 이 기능은 이런 의미였구나’, ‘이게 아니라 저거였구나’ 하는 깨달음을 얻게 되는 경우도 종종 발생합니다. 이런건 시니어도 미리 예상하지 못한, 사업에 내재되어 있는 본질적인 불확실성으로 인한 상황입니다. 그런데 주니어분들은 이렇게 알게 된 새로운 이해를 코드에 잘 반영하지 않습니다. ‘나중에 기회가 되면 해야지…’ 하고는, 그런 것들이 켜켜이 쌓여갑니다. (시니어들은 그보다는 더 자주, 더 작은 단위로 부단히 반영하곤 합니다.)

그보다는, ‘나중에 무엇이 필요하게 될지’는 지금 모두 예측하기 어려우며, 지속적으로 이 코드를 개선해나갈 수밖에 없다는 관점을 가지고, 일단 지금은 현재 아는 범위 안에서 적당한 수준의 확장성을 가진 기능으로, 그 기능 범위 안에서는 높은 품질로 설계를 하고 코드를 만들다가, 새로운 요구사항이나 필요가 생기면 그것을 설계와 코드에 반영해나가는 식으로 개발을 해나가는 전략이 필요합니다.

웜블러드에서는…

웜블러드에서는 지금 우리가 사용자들과 시장의 필요에 대해서 완벽하게 알지 못한다는 것을 인지하고 있습니다. 그래서 여러 팀원들이 각자의 의견을 내어 논의하되, 현재 수준에서 말이 되고 적정한 수준의 설계와 기획을 하고, 빠른 속도로 출시해서 실제로 사용자와 서비스에 대해서 학습(validated learning)하며, 새롭게 알게 된 것들을 코드와 설계에 꾸준히 반영해나갑니다.

최근의 한 사례로, 커뮤니티 게시판에 댓글이 필요해서 댓글을 개발했었는데, 사업을 전개해나가다보니 그게 분양관리시스템 용도로, 또 딜 제안이나 서비스 의뢰의 댓글 기능 용도로도 사용될 수 있겠다는 것을 알게 되었습니다. 전에는 이게 어디에까지 범용적으로 사용될지 몰랐기 때문에 게시판 용도로만 개발을 했었는데, 어느 시점에서 비슷한 기능들이 여기 저기에 사용되면서, 파편화된 채로 내버려두지 않고 설계적으로 꾸준히 통합을 진행하면서 개발을 이어나가고 있습니다. 그리고 이러한 상황은, 사업의 전개 과정에서 자연스러운 과정이라고 생각하고 있습니다.

때문에, 미리 스펙이 완전히 정해져 있어야 확실하고 견고한 시스템을 만들 수 있다고 생각하는 분들, 한두달 사이에 사업의 우선순위가 바뀌며 설계를 계속 변경해가야 하는 상황을 불편하게 여기시는 분들은 웜블러드의 현재 개발 스타일에 불편을 느끼실 수 있겠습니다.

결언

기술 부채는 세간에 알려진 것처럼, 단순히 ‘일단 대충 만들고, 나중에 땜빵하자’, 또는, ‘일단 대충, 나중 땜빵은 마치 빚을 얻는 것처럼 나쁜 것이니, 그렇게 하면 안되고 신중을 기해서 꼼꼼히 개발해야 한다’라는 것으로 이해되기에는 좀 더 심오한 내용을 품고 있습니다. 그리고 이는 애자일의 핵심과도 맞닿아 있습니다.

기술 부채가 오명을 벗고 좀 더 본래의 의미로 이해되어, 워드가 OOPSLA 92에서 발표하며 원래 의도했던 것처럼 여러 개발팀에서 제대로 활용되어서, 여러분들의 프로젝트에서도 “시장의 다양성에 신속하고 효과적으로 대응”하는데 도움이 되었으면 합니다.