코드 정리는 돈이 되나? - Tidy First?
소프트웨어는 돈이다
소프트웨어는 왜 개발될까요? 순전히 개발자 개인의 소소한 재미를 위해서 만들어지는 경우도 있지만 거의 모든 소프트웨어는 돈을 벌기 위해 개발됩니다. 직접 패키징되어 판매되기도 하고 구독 수수료를 지급하는 SaaS 의 형태로 판매되기도 합니다. 사용하는 시점에 직접 대가를 지불하지 않는 소프트웨어 일지라도, 개인이나 기업에게 의미 있는 경제적 가치를 직간접적으로 가져다 줄 수만 있다면 그 지속 가능성을 위해 기업에 소속된 개발자들의 소스코드 기여나 스폰서십 등 시점과 형태의 차이는 있지만 어떤 식으로건 경제적 비용이 지불되기 마련입니다.
당신이 기업에 소속된 개발자라면 코드를 짜는 이유는 더 말 할 것도 없이 회사가 돈을 벌기 위해서 입니다. 시스템 자원을 효율적으로 사용하도록 최적화된 코드, 아름답고 깔끔한 코드, 기능 변경과 추가에 유연한 구조, 빈 틈 없이 촘촘하게 짜여진 단위 테스트와 통합 테스트 같은 것들은 결국 돈을 벌 수 없다면 무용지물입니다. 개발자가 해야 하는것은 고객 또는 회사가 원하는 가치를 창출하기 위한 기능을 기한 내에 개발해서 전달하는 것입니다.
좋은 소프트웨어 구조의 이데아
그러나 같은 기능을 제공한다면 잘 설계된 소프트웨어가 가져다 주는 장점은 명확합니다. 특히 라이브 서비스를 계속하는 게임이나 웹 기반의 비즈니스 서비스라면 런칭 이전보다 런칭 이후 계속해서 유지보수하면서 기능을 추가 변경하는 비용이 훨씬 큽니다. 시간이 지남에 따라 변화에 대응할 수 있는 구조가 잘 갖추어 지지 않았다면 변경의 비용은 점차 기하급수적으로 커질 것이고 결과적으로 소프트웨어의 가장 중요한 목적인 ‘돈 벌기’를 위한 기능 개발은 늦어지겠지요.
결국, 좋은 구조를 갖춘 소프트웨어를 설계하기 위한 노력들도 그 주된 동기는 소프트웨어 개발 비용을 효율적으로 유지하기 위함입니다. 기술 환경의 변화에 따라 그 구체적인 형태와 방법은 달라져오긴 했지만 소프트웨어로 돈을 버는 행위가 시작되어 온 이후로 이에 대한 노력은 변함없이 계속되어 왔습니다. 하지만 그러한 방법론을 이야기하는 서적이나 글에서는 ‘변경에 유리하다’ 거나 ‘장애를 미연에 방지할 수 있다’ 와 같은 해결 가능한 세부 각론에 대해서 이야기하지 좋은 소프트웨어 설계의 근원적인 동기(돈) 에 대해서는 좀처럼 이야기하지 않습니다. 의도적인 부분도 있겠지만 사실 너무 당연해서이기도 할겁니다.
또 어떤 사람들에게는 그러한 방법론들이 좋은 소프트웨어 구조의 어떤 절대적인 ‘선(善)의 이데아’가 있다고 믿게 만들기도 합니다. 하지만 대부분의 ‘야생’(켄트 벡의 표현을 빌려) 개발 현장에서는 그런 선에 가까운 프로젝트는 좀 처럼 찾아보기 힘듭니다. 사실 어느 정도 괜찮은 프로젝트와 진흙탕 같은 프로젝트 정도가 있을 뿐입니다. 심지어 내 손을 거친 프로젝트여도 꼭 예외는 아니라 좌절하곤 합니다.
야생의 프로젝트에 지쳐 레거시 정리라는 목표 하에 프로젝트를 갈아엎거나 기존 코드의 대규모 리팩터링을 목표로 하고 실행해본 경험이 몇번 있습니다. 그러나 그런 고통스러운 대규모 작업을 거친 후 지금 시점에서 그 프로젝트를 다시 살펴 보았을때 여전히 프로젝트가 선에 가깝게 잘 가꾸어지고 있는지 돌아보면 물음표가 남습니다. 여전히 아쉬운 부분이 군데군데 생겨나 있곤 합니다. 소프트웨어는 실시간으로 녹슬어 가는 존재니까요.
그리고 그것이 정말 비용 효율적인 선택이었는지에 대한 물음에도 시원하게 답하기는 어렵습니다. 언젠가 몇년 후에는 기술부채를 끝장내줄 은탄환이 될 것만 같은 방법론, 아키텍처, 기술들의 안개가 다시 프로젝트 현장을 둥둥 떠다닐 것이고 제가 아닌 다른 누군가에 의해 이런 일들이 반복될지도 모릅니다.
조금씩 (비용 효율적으로) 가는 길
고비용에 조금 씁쓸한 뒷맛이 남는 대규모 개편이 반복되는 이유는 사실 의외로 오히려 큰 일을 계획해서 일을 벌이기가 쉬워서 일지도 모릅니다. 일견 폼도 꽤 나는 큰 작업에 기능 개발은 신경쓰지 않고 리팩터링에만 집중할 수 있으니까요. 이에 비해 평소에 꾸준히 기능개발을 병행하면서 적절한 순간에 적절한 규모로 내부 구조를 개선하는 작업을 꾸준히 하는 것은 쉽지 않습니다. 이것만 고쳐야지 하다가도 어느 순간 리팩터링의 늪에 빠져서 ‘나 지금 뭐 하고 있는거지?’ 라는 생각이 번쩍 들기도 하고, 반대로 기능 개발은 코드 몇줄만 고치면 당장 해결할 수 있는데 굳이 구조 개선을 평소에 병행해야 할 필요성을 느끼지 못하기도 하니까요.
켄트 벡의 <Tidy First?> 를 요약하면 결국 기능개발과 병행해 코드 정리(구조 개선)을 어떻게 잘 해나갈것에 대한 이야기입니다. 사실, 코드를 어떻게 리팩터링 하고 개선 사이클을 안전하게 가져갈 것인가에 대한 구체적 방법론에 대한 이야기들은 테스트 주도 개발이나 리팩터링에 관한 내용을 접해 본 개발자들이라면 그리 생소한 이야기는 아닙니다. (물론 실천은 쉽지 않지만)
개인적으로 흥미로웠던 부분은 코드 정리에 대한 일종의 휴리스틱 프레임워크를 세우는 부분이었는데요, 코드 정리는 하지 않으면 장기적으로는 기술 부채가 될 수 있을지언정 당장 경제적 가치를 가져오는 작업은 아니고 언제, 얼만큼 하느냐도 협업하는 동료와 의견이 다를 수 있기 때문에 방향 판단을 할 수 있는 기준점이 필요하다는 말에 공감이 되었기 때문입니다.
의외로 켄트 벡은 무조건 기능 개발과 코드 정리를 병행해야 한다고 말하지는 않습니다. (그래서 책 제목 끝에 물음표가 붙어있는 걸지도 모릅니다.) 대신 현금흐름 할인(현재가치)과 와 옵션의 개념을 빌려와 우선순위를 판단해볼 것을 제안합니다. 코드 정리건 기능 개발이건 결국 비용(현금)을 사용하는 일입니다. 우리가 만든 소프트웨어는 수익을 창출할 것이므로 비용 대비 손익을 따져 보자는 것이지요.
수익을 창출하는 데 코드 정리는 당장 직접적으로 기여하지는 않습니다. 일종의 옵션 투자라고 볼 수 있습니다. 반면 기능 구현은 당장 얻을 수 있는 수익에 바로 기여합니다. 따라서 어떤 기능을 구현하는데 코드 정리후 기능 구현하는 것과 그냥 구현하는 것 중 전자가 비용이 낮다면 무조건 코드 정리가 선행되어야 하겠지요. 그 반대의 상황이라면 손익을 좀 더 고민해 봐야 합니다. 코드 정리라는 투자행위를 했을때 더 많이, 더 일찍, 더 높은 확률로 수익을 가져다 줄 수 있는지 혹은 더 적게, 더 늦게, 더 적은 확률로 비용 지출을 할 수 있게 해주는지를 생각해 봐야 합니다. 기능 구현을 했을 때 얻을 수 있는 수익이 불확실 하거나, 개발 기간이 길게 잡혀있거나, 기능이 변경될 가능성이 높을수록 옵션(코드 정리)의 가치는 커진다고 켄트 백은 설명합니다.
다만 손익에 기반하여 저울질 하더라도 모든 작업의 경제성을 정확히 판단할 수는 없고 결국 개발은 사람이 하는 것이기에 개발이 더 즐겁고 편해지다는 단순한 이유로 코드 정리를 해도 된다고 말합니다. 언제나 그 작업이 경제적 인센티브와 반대되는 일이라는걸 염두에 두고 있다는걸 전제로 해야겠지만요.
Cost First?
유명한 개발서들은 그만큼 많은 개발자들에게 영향을 끼치기 때문에 어떤 사람들은 책이 말하는 온전한 의도를 폭넓게 받아들이기 보다는 구체적인 실행 방법론이나 규칙에만 교조적으로 집중하는 경우도 있어 주변의 반감을 사거나 오해받는 경우도 많아 보입니다. DDD, Clean Architecture 가 그렇지만 TDD 만큼은 아닐 겁니다. DHH 가 TDD is dead 를 쓴지도 벌써 10년 전인데 아직까지도 켄트 벡이 TDD Isn’t Design 같은 이야기를 해야 하는 것을 보면 어쩌면 TDD, XP 와 같은 책에서 무수히 반복되었던 이야기를 <Tidy First?> 에서 ‘작게 나눠’ 다시 시리즈로 시작하는 이유를 짐작하게 합니다.
결국 좋은 소프트웨어 구조란 개발, 개선하는 비용에 대한 문제입니다. ‘콘스탄틴의 등가성’ 에서 말하듯 이는 곧 소프트웨어 복잡도에 대한 문제이기 때문이지요. 응집도, 결합도에서 출발해 SOLID 와 같은 객체지향 설계 원칙, DDD, TDD 를 비롯한 방법론과 각종 아키텍처가 근본적으로 해결하고자 하는 문제의 뿌리가 복잡도 제어와 비용 제어라는 것을 받아들인다면 더 나은 프로그래밍을 할 수 있는 방법에 대한 실마리를 찾을 수 있지 않을까 합니다.