이 글의 전편
얼마 전 "소프트웨어 성장 이론"이라는 글을 썼었습니다. 빌드 메타포에 대해서 말씀드렸는데요. 빌드 메타포는 1958년쯤부터 사용된 개념인 것 같다고 말씀드렸습니다. 그런데 브룩스는 1986년 발표한 <은 총알은 없다>에서 빌드 메타포가 너무 오래 사용되었다고 했거든요. 그 이유를 추정해 보자면, 아마도 "폭포수 개발"방식 때문이 아닐까 싶습니다.
1970년대 초부터 사용된 폭포수 개발 방식의 문제점이 드러나기 시작하면서, 다시 반복적, 점증적으로 소프트웨어를 개발해야 한다는 목소리들이 나오기 시작했습니다. 그래서 브룩스는 <맨 먼스 미신>과 <디자인 오브 디자인>에서 "폭포수 개발"방식을 버려야 한다고 말하거든요. 게다가 1986년쯤이면 우리가 잘 아는 "스크럼" 개발 방식이 사용되기 시작할 무렵입니다. 미 국방성은 소프트웨어 개발 표준 프로세스로서 폭포수 개발 방식을 사용하지 않기로 했는데, 그것 역시 1980년대 중반 일입니다.
브룩스는 빌드 메타포를 버리고 성장 메타포를 사용해야 한다고 말하고 있습니다. 빌드 메타포를 사용하기엔 소프트웨어가 너무 복잡해져가고 있기 때문입니다. 관점을 바꿔서 자연을 보면, 자연계에는 인간이 상상할 수 없을 만큼 복잡한 생물들이 자라나고 있습니다. 안정적으로 성장하지만 강력하고, 다양하고 자기 보호적이며 스스로 갱신할 수 있는 구조를 가집니다.
그래서 저는 브룩스가 제시한 주장을 식물을 성장시키는 관점에서 3단계로 나눠봤습니다.
첫째, 씨 뿌리기 : 소프트웨어가 일단 실행 되도록 (작게) 만든다.
둘째, 성장시키기 : 점증적인 개발로 성장시켜간다.
셋째, 가지치기 : 백트래킹을 규칙으로 잘못 성장한 가지는 가지치기 할 수 있어야 한다.
여기까지가 지난 글에서 정리한 내용입니다. 그럼 이번엔 그 이후에 대한 이야기를 해보도록 하겠습니다.
애자일 선언
앞에서 말씀드렸던 것처럼 1986년쯤이면 스크럼이 시작하던 시기입니다. 기술 발전은 다중성이라는 특징을 지니기 때문에, 비슷한 주장을 하는 사람들이 비슷한 시기에 나타나기 마련입니다. 폭포수 개발 방식의 한계점을 극복하기 위해서 1971년 논문을 인용하여 소프트웨어를 빌드가 아니라 "성장"시켜야 한다고 주장했던 브룩스가 있다면, 개발자로서 소프트웨어 개발을 하면서 그 과정에서 학습한 결과를 소프트웨어 개발 방식으로 집대성하는 이들도 있었습니다. 그중 반복적인 프로세서가 기틀이 된 개발 방식을 선호하는 사람들이 모여서 "애자일 선언"을 발표합니다(2001). 1980년대 중반부터 반복적인 개발 방식을 발전시켜왔던 여러 분파가 모여 같은 방향성을 "선언문"이라는 형식을 빌려 만든 것이죠.

첫 번째 단락에서 이들은 오랜 경험과 학습을 통해 이런 주장을 하게 된 것을 알 수 있습니다.
우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을
도와주면서 소프트웨어 개발의 더 나은 방법들을 찾아가고
있다. 이 작업을 통해 우리는 다음을 가치 있게 여기게 되었다
두 번째 단락이 정말 재미있는데요. 왼쪽은 빌드 메타포에서 오는 부산물들 오른쪽은 성장 메타포를 진행하기 위한 개념들이기 때문입니다.
이 말은, 왼쪽에 있는 것들도 가치가 있지만,
우리는 오른쪽에 있는 것들에 더 높은 가치를 둔다는 것이다.
마지막 단락이 좀 애매한 표현인데요. "소프트웨어 성장 이론"이라는 관점으로 이 문장을 바라보면, 정말 깔끔하게 정리할 수 있습니다.
'성장을 위해서 왼쪽 항목의 일을 해라, 성장을 방해한다면 하지 마라'
그럼, 이제 애자일 선언을 감안해서, "소프트웨어 성장"에서 파생할 수 있는 메타포 몇 개를 더 정리해 보도록 하겠습니다.
씨 뿌리기
포괄적인 문서보다 "작동하는 소프트웨어"를 중요하게 여긴다는 의미는 MVP(Minimum Viable Product)라는 용어에 함축되어 있습니다. 전 <린 소프트웨어 개발>에서 처음 보았던 단어였었는데요. 요즘은 업계에서 보편적으로 사용하는 용어가 되었습니다.
이중 'V'에 해당하는 Viable이라는 단어를 사전에서 찾아보면, "생존 가능한", "생명을 가질 수 있는", "실행 가능한" 과 같은 표현들이 나옵니다. 그렇습니다. "씨앗"인 것입니다. 가장 최소한의 기능만 가지고 바로 실행해 볼 수 있는 상태를 말합니다.
MVP로 소프트웨어를 만들어서 바로 배포하고, 고객과 협력하는 과정을 거치면서 성장시켜가자는 것이 애자일 선언의 주장입니다. 그 과정은 개발자들 간의 상호 작용으로 이루어지게 되겠죠.
1986년 브룩스의 주장은 2001년에 와서 상당히 구체적이고 보편적인 실천법이 되었음을 알 수 있습니다
그럼 메타포를 좀 더 확대해 나가보도록 하겠습니다. 식물이 자라려면, 몇 가지 조건이 필요합니다. 물, 햇빛, 토양 뭐 이런 것들이죠. 이중 물을 먼저 이야기해 보도록 할까요?
治水 (물을 다스림)
소프트웨어를 성장하는 대상으로 본다면, "사용자 스토리"는 물과 같습니다. 식물이 자라려면 물이 반드시 필요하듯, 소프트웨어가 성장하려면 '사용자 스토리'가 필요합니다.
다만, 사용자 스토리 유입에는 몇 가지 유의할 것들이 있습니다.
첫째, 물을 적당히 줘야 식물이 자랍니다.
씨앗이 새싹이 되고 새싹이 점점 자라나는 데는 많은 물이 필요하지 않습니다. "사용자 스토리"도 마찬가지입니다. 현재 소프트웨어의 크기에 맞게 적당한 분량의 '사용자 스토리'가 유입되고, 너무 많은 분량을 한꺼번에 밀어 넣는 일은 없어야 합니다.
빌드 메타포 관점에서는 모든 요구사항이 한꺼번에 시작 시점에 유입되는 걸 선호했습니다. 어떤 소프트웨어를 만들어야 하는지 알려줘야 만들게 아니냐고 말할 수도 있지만, 지금까지 수십 년의 경험으로 사용자 요구사항을 완벽하게 만든다는 건, 상당히 많은 노력이 필요한 일이고, 그런 노력을 기울이고 장시간 동안 사용자 요구사항을 만들어도 업계가 그보다 빠르게 변화하고 있다면 아무 소용이 없다는 것을 알게 되었습니다.
시시각각 변하는 시장의 상황을 반영하는 "사용자 스토리"가 소프트웨어가 성장할 만큼씩 유입돼야 가장 효율적인 성장을 이끌어 낼 수 있습니다.
둘째, 물은 썩지 않아야 합니다.
화분에 물을 한꺼번에 주면 뿌리가 썩어서 식물이 죽습니다. 그처럼 사용자 요구사항을 한꺼번에 밀어 넣는 행위는 물을 섞게 합니다. 게다가 시장 상황을 반영하지 못하는 '사용자 스토리'가 정체하고 있다면 이 또한 썩게 될 겁니다.
매번 스프린트( 또는 이터레이션, 반복 주기)마다 사용자 스토리 목록 (프로덕트 백로그)은 우선순위를 재점검해서 물을 휘젓는 것 같은 노력을 가해야 가장 깨끗한 물이 우리의 소프트웨어를 성장시키게 될 겁니다.
셋째, 물은 영양가 있어야 합니다.
개발 조직에서 '사용자 스토리'를 운영하려고 할 경우 개발 외 조직의 지원이 없으면, '사용자 스토리'가 영양가 없게 됩니다. '사용자 스토리'는 고객의 니즈를 충족시키는데, 그 시점에 가장 중요한 것부터 우선순위가 결정되어야 할 뿐 아니라. 직접적으로 회사의 매출에 이익과 연결될 수 있어야 합니다.
그냥 기획자의 막연한 추측에서 나온 "사용자 스토리"는 영양가가 없을 수밖에 없습니다. 개발자가 하고 싶은 데로 "사용자 스토리"를 마구 만들어 내는 것도 역시 영양가가 있을 리 없습니다.
브룩스가 언급했던 "본질적인 작업"을 하게 만드는 "사용자 스토리", 그런 사용자 스토리가 흐르는 지하수처럼 끊임없이 공급되어, 훌륭한 소프트웨어로 성장하게 되는 그림을 상상해 보시기 바랍니다.
토양
소프트웨어가 성장하기 위해서는 토양이 필요합니다.
과거 화전민들은 땅을 개간할 때 가장 처음 콩을 심었다고 합니다. 콩은 그 뿌리에 '뿌리 혹 박테리아'라는 녀석들이 기생하게 되는데요. 콩 뿌리에 살면서 질소를 공급하는 역할을 하기 때문에 콩에는 단백질이 풍부하게 됩니다. 콩을 심으면 그 흙은 질소가 많은 흙이 되고 다른 식물도 건강하게 자랄 수 있는 흙이 됩니다. 천연 질소비료인 셈이죠.
이와 마찬가지로 우리의 소프트웨어를 성장시키기 위한 토양을 만들기 위해 콩을 심는 일부터 선행해야 합니다.
첫째, 건물을 짓고, 제품을 만들던 시멘트 바닥에는 소프트웨어를 성장시킬 수 없습니다.
절차에 따라 프로세스를 진행하는 것보다 서로 협력하는 문화가 퍼져야 합니다. 비단 개발 조직뿐만 아니라 회사 전체에 애자일 문화가 유입되어야 합니다. 수분("사용자 스토리") 이 소프트웨어 성장에 영향을 미칠 수 있도록 공급되려면 애자일 토양이 필요하거든요.
빌드 메타포는 조직을 나누고 조직별 프로세스를 나누고 프로세스에 의해 개개인이 움직이는 걸 당연하게 보게 만들었지만, 그렇게 움직이게 되면, 제대로 된 "사용자 스토리"가 소프트웨어 개발 조직에 유입되어 소프트웨어 성장에 이바지할 수 없습니다.
"사용자 스토리"를 기준으로 각 조직에 있는 사람들 모두가 상호작용하고 협력할 수 있게 토양을 바꿔야 합니다.
둘째, 물길을 내야 합니다.
조직보다, '사용자 스토리'가 우선하게 해야 합니다. 엘리 골드렛은 <The Goal>에서 "제약 이론"(TOC: Theory of Constraints)를 주장했습니다. 간결하게 말하면 "제약 이론"은 '병목구간 외에 개선 활동은 쓸데없는 짓'이라는 뜻입니다.
회사의 리더들은 프로세스 개선을 많이 이야기하는데요. 프로세스 개선을 하기 위해 중요한 건, 절차 보다 흐름입니다. 어떤 절차를 갖는 프로세스를 갖추느냐가 아니라 흐름을 원활하게 하려면 어떻게 해야 하느냐가 중요하다는 말입니다. 그렇게 해야 리드타임(사용자 요구에 따라 제품이 완료되어 출시되는 시간)이 짧아지게 되고, 빠르게 시장에 적응할 수 있는 기틀이 생깁니다.
'사용자 스토리'를 기준으로 프로세스를 정리한다면, 이런 일을 할 수 있습니다. '사용자 스토리' 원활하게 흐르고 있지 않다면, 그 구간이 병목입니다. 거기를 개선하면 되죠. 만약 사업 부서에서 썩은 물(잘못된 '사용자 스토리')를 뿜어내고 있다면, 거기가 병목입니다. 별것 아닌 '사용자 스토리'가 개발팀에서 정체되어 소프트웨어 성장으로 연결되지 않고 있다면, 거기가 병목입니다. 분명 잘못된 소프트웨어 아키텍트와 소프트웨어 아키텍트와 어울리지 않는 조직구조를 고집하고 있을 겁니다.
셋째, 토양을 가꾸는 책임은 모두에게 있습니다.
땅에 콩을 심으려 해도 지주가 방해한다면 소용이 없습니다. 물길을 내려고 해도 물을 흘려보내지 않으면 아무 소용이 없습니다. 소프트웨어 성장을 위한 토양을 만드는 건, 가드너(정원사 gardener)만의 힘으로는 할 수 없는 일입니다.
인사팀은 백 년 전에 나온 "과학적 관리기법" 신봉자로서 프레드릭 테일러 유령( 미래학자 다니엘 핑크는 <드라이브>라는 책에서 테일러를 유령으로 묘사합니다. )의 속삭임에만 귀 기울이고 있고, 기업의 리더는 조직 구조가 주는 테스토스테론에 취해서 경주마처럼 한곳만 바라보고 뛰어가고 있다면 ( 테스토스테론은 남성호르몬입니다 그런데 <승자의 뇌>에서는 테스토스테론이 권력과 관련되어 있고 "경주마의 눈 가리게를 사람에게 씌운다고 설명하고 있습니다. )
소프트웨어가 제대로 만들어진다는 보장은 없습니다. (가끔 운이 좋은 경우도 있지만요)
가드너(정원사)의 도구
소프트웨어를 성장시키는 가드너(우리가 개발자라고 말하는 그들을 성장이라는 메타포이니만큼 이렇게 불러보도록 하겠습니다)들에게는 도구가 필요합니다. 이제 "변화에 대응" 하는 가드너의 도구에 대해 알아보도록 하겠습니다.
첫째 TDD입니다.
10년 전에 번역 출간된 <테스트 주도 개발로 배우는 객체지향 설계와 실천>이라는 책은 원서 제목이 <Growing Object-Oriented Software, Guided by Tests>였습니다. 자바 언어에서 TDD를 어떻게 사용해야 하는지 설명한 이 책의 제목이 "Growing"이라는 건, 자바 프로그래밍 언어로 소프트웨어를 성장시킬 때 도구로 TDD를 쓸 수 있다는 의미이겠죠.
TDD는 테스트 주도 개발(Test driven development)의 약자로 XP(익스트림 프로그래밍) 개발 방식의 창시자인 켄트 백이 만든 개발 방식입니다. "빌드 메타포" 관점으로 접근할 때, 테스트는 제품을 모두 만든 다음 제대로 만들었는지 확인하는 도구일 뿐이지만, "성장(Grow) 메타포"로 접근할 때, 테스트는 정원사가 소프트웨어를 성장하도록 하게 하는 길라잡이입니다.
여기서 지난번 글에서 언급했던 프레드릭 브룩스의 개념을 다시 한번 상기해 보도록 하겠습니다. 프레드릭 브룩스는 <은 총알은 없다>에서 우리가 소프트웨어 개발에서 개선하려고 했던 것들은 "부차적 작업"에 해당하는 것들이기 때문에 "본질적 작업"에 해당하는 부분을 개선할 수 없고 "은 총알"에 해당하는 단번에 이루는 개선은 있을 수 없다고 설명합니다. 다만 본질적 작업을 하는 데 도움을 받을 수 있는 것들을 이야기했는데요. 그중에 하나가 "성장 메타포"였습니다.
따라서, 가드너(정원사)의 도구로 TDD가 사용된다는 의미는 TDD를 사용하므로 "본질적 작업"에 도움을 받을 수 있다는 것입니다. 즉 TDD를 하는 과정에서 소프트웨어의 "추상적 개념 구조"를 완성되어가야 합니다.
빌드 메타포에서는 이를 "설계"라고 불렀습니다. (소프트웨어가 필요한 추상적 구조를 미리 정하고 그 구조에 소프트웨어를 끼워 맞추었습니다.) 성장 메타포에서는 '설계'라는 용어로 대변하기엔 애매합니다. 청사진을 만들 수 없는 설계가 있을 수는 없거든요. 그래서 "창발적 설계"라는 용어를 사용하는지도 모르겠습니다.
<테스트 주도 개발>에 부록으로 첨언되어 있는 "마틴 파울러"의 설명에 따르면 TDD는 "딱 하나의 공만 공중에 띄우는 저글링"의 정신 상태를 만들어 준다고 말합니다. 이는 성장하는 소프트웨어의 다음 한 단계 성장만을 가드너가 집중하게 만드는 기능이 TDD 있다고 연결할 수 있겠네요. 소프트웨어는 상당히 복잡한 상황과 상태를 관리해 나가는 도구입니다. 그런데 이런 모든 상태를 작업자의 머릿속에서 관리하기는 힘들죠. 그럼 그런 상태를 분해하고 나눠서 단순하게 만드는 도구가 필요합니다. TDD는 가드너의 머릿속에 그걸 하게 만드는 겁니다.
그 결과, 추상적 구조를 만드는 작업이 수월하게 이루어져 가도록 TDD는 물리적인 도움을 주게 될테니 정원사의 도구라고 말할 수 있습니다. (TDD에 대한 더 자세한 설명은 다른 블로그와 책을 참고하시기 바라요)
둘째는 CI입니다.
역시 켄트 백의 익스트림 프로그래밍 기법의 실천법 중 하나입니다. CI(Continuous integration)는 지속적인 통합이라는 뜻이죠. 제 경험에 의하면 많은 조직이 "지속적"은 빼고 쓰는 개념입니다. ( 제 경험에 의하면 최악의 CI는 매주 진행하는 범인 색출 프로그램이었습니다. 빌드가 실패하도록 만드는 것은 회사 이익에 반하는 행동이라고 정의 내리고 이런 결과를 만드는 개발자를 색출하는 도구로서 CI를 썼거든요. )
빌드 메타포로 보면, 통합은 제품 개발 막바지에 하는 일입니다. 한번 하면 되는데, 절차가 복잡하니 툴을 쓰는 정도의 이해가 가능합니다. 하지만 성장 메타포로 보면 지속적인 통합은 TDD로 만든 마디마디가 줄기로 성장하게 만드는 과정입니다. 얼마나 자주 CI가 작동하냐는 얼마나 안정적으로 소프트웨어를 성장시켜 나갈 수 있느냐를 알려주는 지표인 셈이죠.
안정적인 줄기(branch : git과 svn같은 소스코드 버전 관리 시스템의 그 용어를 말합니다.)를 얻기 위한 도구로서 CI를 써야 합니다. 되도록 빨리 수정된 코드가 통합되어 전체 코드에 어떤 영향을 미치는 지, 자동적으로 확인하고 가드너가 TDD를 가지고 작업한 또다른 마디가 무리없이 안착할 환경을 만들어야 합니다.
(CI/CD에 대한 더 자세한 내용은 다른 문서들을 참고 하세요. 다만 성장 메타포 관점에서 해석하며 보시기 바랍니다.)
엉켜있는 나무
이미, 소프트웨어 복잡성으로 인해 빌드 메타포가 한계를 넘어선 현 시점에도 우리는 소프트웨어를 빌드 메타포로 보고 있습니다. 그래서 우리가 만든 소프트웨어는 엉켜있는 나무가 되는 경우가 많네요.
설계라는 유리상자 안에서만 자라다 보니, 상자 가득 나무가지들이 꼬이게 되고 결국 변화를 대응하려면, 엄청난 시간과 노력이 필요한 상황이 되었습니다. 개발조직을 위한 코드, 개발자들을 관리하기 위한 코드, 딱딱한 코딩 컨벤션은 나무가지와 나무가지를 연결하고 가지치기가 힘든 코드를 만들어서, 죽은 가지들이 다른 가지와 엉켜서 매달려 있는 상황을 만들었죠.
쓰레기 더미처럼 변한 레포지토리에 가지들(branch)들은 존재의 이유없이 쓰레기장 폐기물처럼 쌓여가고 있고
조직간의 벽과 프로세스만을 위한 절차들은 결과적으로 힘을 잃은 사용자 요구사항을 개발자들에게 전달하며, 어디가 병목인지 찾기 힘든 상황은 개선이 불가능한 조직, 학습이 불가능한 조직을 만들어가고 있습니다.
그래서, 로버트 C 마틴은 <클린 아키텍처>에서 다음과 같이 탄식합니다.
나를 포함해서 우리 대다수는 대체로 이러한 경험을 했다.
훌륭한 소프트웨어 설계를 바탕으로 작업하면서 즐거움을 느끼기보다는,
형편없는 소프트웨어 설계와 맞서 싸우는 일을 훨씬 더 자주 맞닥뜨린다.
약 40년 정도 늦긴 했지만, 프레드릭 브룩스의 말을 귀기울이고, 근본적인 원인인 빌드 메타포를 성장 메타포로 바꾸는 건, 어떨까 싶습니다.
'바람보기' 카테고리의 다른 글
지식(지혜) 사회의 생존방식 (2) | 2025.02.17 |
---|---|
개발자, 책 읽기 그리고 제텔카스텐 (0) | 2025.01.27 |
더 나은 프로그래머 되는 법 (0) | 2024.05.26 |
소프트웨어 성장 이론 (0) | 2024.05.25 |
켄트 벡의 Tidy First ? (1) | 2024.04.30 |