나의 노트

코드와 텍스트의 공동 소유권

Collective Ownership of Code and Text

번역 워드 커닝햄(Ward Cunningham)과의 대담, 2부 빌 베너스(Bill Venners) 작성 2003년 12월 1일 www.artima.com/articles/collective-ownership-of-code-and-text ↗

요약 워드 커닝햄이 빌 베너스와 함께 위키(Wiki)를 공동 코드 소유권의 모델로 설계한 방법, 소유권에 대한 자부심을 고취하는 집단적 인센티브, 그리고 실수에 대한 비용을 없앰으로써 의견 불일치를 해결하는 방법에 대해 이야기합니다.

소프트웨어 커뮤니티에서 워드 커닝햄은 아이디어의 원천으로 정평이 나 있습니다. 그는 객체 발견을 돕는 기법인 CRC 카드를 고안했습니다. 또한 소프트웨어 패턴의 발견과 문서화를 돕기 위해 세계 최초의 웹 기반 협업 저작 도구인 위키(Wiki)를 발명했습니다. 가장 최근에 커닝햄은 익스트림 프로그래밍(XP)의 여러 기법에 주된 영감을 준 인물로 꼽힙니다.

2003년 9월 23일, 빌 베너스는 덴마크 오르후스에서 열린 JAOO 컨퍼런스에서 워드 커닝햄을 만났습니다. Artima.com에 여러 회에 걸쳐 연재될 이 인터뷰에서 커닝햄은 위키와 익스트림 프로그래밍의 여러 측면에 대한 통찰을 제공합니다.

1부: 위키를 통한 탐험에서 커닝햄은 협업적 탐험을 위해 위키를 사용하는 방법과 위키 작성자와 독자 간의 트레이드오프에 대해 논의했습니다.

이번 2부에서 커닝햄은 위키를 공동 코드 소유권의 모델로 설계한 배경, 소유권에 대한 자부심을 위한 집단적 인센티브, 그리고 실수에 대한 비용을 제거하여 의견 불일치를 처리하는 방법에 대해 이야기합니다.

코드와 텍스트의 공동 소유 (Collective Code and Text) 빌 베너스: 익스트림 프로그래밍(XP)의 공동 코드 소유권(collective code ownership)이라는 개념을 보면, 모두가 모든 것을 책임지는 위키가 떠오릅니다.

워드 커닝햄: 그건 전적으로 의도한 것입니다. 제가 위키를 만들기 몇 달 전, 우리는 논쟁을 벌이고 있었습니다. 아마 켄트 벡(Kent Beck)과 제가 한 편이었을 겁니다. 당시 소프트웨어 공학의 지배적인 통념을 굳게 믿는 사람들이 반대편에 있었죠. 우리는 "공동 코드 소유권은 좋은 것이다"라고 주장했습니다. 그들은 "말도 안 된다. 책임 소재가 없으면 품질도 기대할 수 없다. 책임을 지게 하는 유일한 방법은 소유권이다. 버그가 줄어들게 하려면 버그를 누군가의 탓으로 돌릴 수 있어야 한다"라고 반박했습니다. 저는 "글쎄요, 그건 틀린 생각입니다"라고 말했죠.

제가 위키를 설계할 때 내린 결정들은 대규모 코드 베이스에서 일어나야 한다고 생각했던 협업 과정을 모델로 만들고 싶은 열망에서 큰 영감을 받았습니다. 저는 위키가 그 과정을 흉내 내기를 원했습니다. 예를 들어, 어떤 코드 뭉치에 문제가 있다고 칩시다. 당신은 해결책을 알지만, 그 해결책은 여러 모듈을 건드려야 합니다. 필요한 리팩터링(refactoring)은 힘든 작업인데, 모든 원작자와 일일이 협상해야 한다면 훨씬 더 힘들어집니다. 당신은 그저 바로잡고 싶을 뿐인데 말이죠.

문제는 코드는 계층 구조로 정리되어 있을지 몰라도, 해결책은 그 계층 구조에 딱 들어맞지 않는 더 많은 차원을 가지고 있다는 점입니다. 계층 구조를 가로지르는 차원에서 해결책을 찾았을 때, 당신은 해결책이 이끄는 곳으로 가서 그것을 적용해야만 합니다. 우리는 종종 사람들이 프로그램에 대해 무언가를 알고 있지만 그 지식을 프로그램에 적용할 수 없는 상황에 부닥칩니다. 왜냐하면, 그 지식이 그들이 그것을 알기 전에 내려진 조직적 결정과 배치되기 때문입니다. 다시 말해, 프로그램이 그 지식의 집합에 대해 저항성을 갖게 되는 것입니다.

빌 베너스: 저항성이요?

워드 커닝햄: 프로그램은 특정 종류의 지식, 즉 예상치 못했던 지식에 대해 저항성을 키웁니다. 처음에 설계된 구조 안에서는 그 지식을 쉽게 표현할 수 없기 때문입니다. 그 구조에 맞지 않는 것을 집어넣기란 쉽지 않습니다.

위키에서도 예상 범위를 벗어난 아이디어에 대해 약간의 저항이 존재하지만, 그 저항은 주로 사람들의 관행에 있습니다. 위키에 글이 많이 쌓일수록 그 자체로 경직되긴 하지만, 누군가 무언가를 바꾸고 싶어 하고 그것을 위해 25페이지를 수정할 의향이 있다면, 그렇게 할 수 있습니다.

예를 들어, 위키에서 일어나는 과정 중 하나는 페이지가 토론에서 에세이로 진화한다는 것입니다. 많은 사람이 토론을 읽고 싶어 합니다. 매일 위키를 방문하는 사람들은 어제 무슨 말이 오갔는지 보고 싶어 하므로 시간순으로 정리된 페이지를 원합니다. 하지만 기여 순서는 학습을 위한 좋은 정리 원칙이 아닙니다. 그래서 페이지들은 토론이 끝날 때까지는 토론 같은 느낌을 줍니다. 나중에 누군가 다시 와서 토론을 읽고, 이른바 '스레드 모드(thread-mode)' 페이지를 '문서 모드(document-mode)' 페이지로 재구성합니다.

종종 코멘트들을 이리저리 옮기고 비슷한 내용을 서로 인접하게 배치하다 보면, 단어의 절반은 잘라낼 수 있다는 것을 발견하게 됩니다. 적절한 위치에 있는 문장 하나가 모든 것을 설명해주기 때문이죠. '워드의 위키(Ward's wiki)'에서는 이 과정을 "리팩터링"이라고 부릅니다. 소프트웨어에서 쓰는 용어죠. 제 위키는 소프트웨어에 관한 것이고 소프트웨어 관련 종사자들이 사용하므로 그렇게 부릅니다. 다른 곳이었다면 아마 '편집(editing)'이라고 불렀을 겁니다. 그래서 제 위키에서 리팩터링은 지속적인 과정입니다. 어떤 것이 이상적이지 않다고 판명되면 다시 리팩터링될 것이라는 가정 하에 이루어집니다. 모든 것은 리팩터링의 대상입니다. 바로 이것이 우리가 소프트웨어에서 보고 싶은 모습입니다.

소프트웨어는 해석이 명확하다는 장점이 있습니다. 기계를 위해 작성되기 때문에, 우리는 그 명확한 해석에 의존해 테스트를 작성할 수 있습니다. 프로그램을 리팩터링할 때 아무것도 손상되거나 잃어버리지 않았는지 테스트할 수 있죠. 반면에 사람을 위해 작성된 위키는 명확한 해석이 없습니다. 제가 "이 문장을 위로 올리고 절반을 잘라내야지. 이 문맥에서는 이해하기 쉬우니까"라고 할 수 있습니다. 하지만 제가 틀릴 수도 있습니다. 저에게는 쉽지만, 다른 사람들에게는 어려울 수 있고, 저에겐 테스트 도구도 없습니다. 그래서 아마 위키는 리팩터링 과정에서 정보를 잃을 수도 있습니다. 위키는 정보가 새는 양동이와 같습니다. 매일 정보를 잃어버리죠. 하지만 더 많은 정보가 들어오기 때문에 순이익은 플러스입니다. 잃어버리는 것이 있더라도, 위키는 항상 어제보다 더 많은 이야기를 담고 있습니다.

품질 좋은 코드를 위한 집단적 인센티브 (Collective Incentives for Quality Code) 빌 베너스: 말씀하신 공동 코드 소유권의 장점은 알겠습니다. 비용은 무엇인가요? 공동 코드 소유권의 단점은 무엇입니까?

워드 커닝햄: 분명 뭔가 있겠지만 지금 당장은 생각나는 게 없네요.

빌 베너스: 소유권에 대한 자부심(pride of ownership)은 어떤가요? 사람들은 공동의 자부심에도 적응하나요? 무언가가 자신의 창작물일 때, 사람들은 그것을 훌륭하게 만들고 싶어 하잖아요.

워드 커닝햄: 저는 공동 소유권이 오히려 그 점에 더 좋다고 생각합니다. 네, 저는 제가 하는 일에 큰 자부심을 느낍니다. 자부심은 저에게 동기부여가 됩니다. 하지만 공동 소유권을 통해 우리는 본질적으로 제가 한 일을 진가(眞價)를 알아봐 주는 훈련된 소수의 커뮤니티를 만들게 됩니다. 반면에 제가 소유권을 가지고 있다면 사람들은 "저건 워드의 모듈이야. 워드의 모듈은 쳐다보기도 싫어."라고 할 겁니다. 어쩌면 그 모듈을 호출해야 할 때 API는 좋아할 수도 있겠죠. 제 모듈의 버그 발생률이 낮은 것에 감탄할 수도 있고요. 하지만 그들은 "음, 워드는 간단한 모듈을 맡았어. 작성하기 쉬운 모듈이었지. 그래서 버그율이 낮은 거야."라고 말할지도 모릅니다. 그들은 모르는 거죠.

사람들이 제가 만든 결과물을 직접 다뤄보면, 그것이 쉽게 다뤄지는지 아닌지 느낄 수 있습니다. '자료를 다룬다(work the material)'는 것은 코드를 가져다가 기능을 조금 더 추가하거나 다르게 작동하도록 조정하는 등 코드에 필요한 작업을 하는 것을 의미합니다. 사람들이 코드를 다루다 보면 제가 의도했지만, 겉으로는 눈에 띄지 않았던 것들을 발견하게 됩니다. "워드, 당신 정말 뛰어나군요"라고 말해야 할 의무는 없지만, 때로는 그렇게 말해주기도 합니다. 그러면 제 자존감이 올라가죠. 소유권에 대한 자부심? 당연히 있습니다.

물론, 모든 줄에 제 이름이 붙어 있지는 않습니다. 사실 코드가 정말 좋아졌을 때는 제가 아니라 그들이 좋게 만들었기 때문일 수도 있습니다. 저는 방향만 잡았고, 그들이 내용을 채우고 훌륭하게 만들었을 수도 있죠. 제가 받을 자격이 없는 칭찬을 받을 수도 있지만, 그들이 다른 사람들에게도 칭찬을 건넬 수 있습니다. 아이디어가 어디서 왔고 누가 공로를 인정받아야 하는지는 꽤 불분명한 문제입니다. 하지만 저는 사람들이 관련된 사람들을 알 때, 그런 모호함을 잘 다루고 기여를 인정하는 데 꽤 능숙하다고 생각합니다. 공동 소유권을 통해 우리는 누군가가 자신의 지성을 어떻게 소스 코드 구문으로 엮어내는지를 보며 그 사람을 알게 되는 사회적 상황을 만들게 됩니다.

빌 베너스: 왜 공동으로 소유된 코드에는 위키 페이지처럼 한동안 무질서해지는 현상이 일어나지 않는 건가요?

워드 커닝햄: 제 생각엔 코드에서도 분명 그런 일이 일어납니다.

빌 베너스: 방금 특정 코드 라인을 누가 작성했는지 항상 명확하지는 않다고 하셨잖아요. 위키 페이지도 마찬가지입니다. 특정 텍스트를 누가 썼는지 항상 분명하진 않죠. 가끔 사람들이 위키 페이지에 "나는 이런 경험을 했다"라고 쓰지만, 독자인 저는 그 "나"가 누구인지 모릅니다. 텍스트와 비교했을 때 공동 코드 소유권이 더 깔끔한 코드를 만들어내는 차이점은 무엇인가요?

워드 커닝햄: 저는 난해한(inscrutable) 코드가 매우 흔하다고 생각합니다. 코드가 작동은 할지 몰라도 작동 방식이 본질적으로 암호화된 것처럼 보일 때가 있죠. 읽는 것이 불가능합니다. 사실 그게 일반적인 경우일 수도 있습니다. 그래서 '무질서하다'는 표현이 딱 맞지 않을 순 있어도, 분명 '읽기 쉽지 않다'는 건 맞습니다. 저는 오랫동안 짝 프로그래밍(pair programming)을 해왔는데, 파트너의 코드를 읽으면서 제 코드라고 착각할 때가 있습니다. 하지만 위키에서는 누군가의 문단을 읽고 제 문단이라고 생각한 적은 없습니다. 아마 코드가 더 고도로 조직화되어 있어서 그럴 수도 있지만, 코드에서의 담론 범위가 훨씬 좁기 때문일 수도 있습니다. 담론의 범위가 어떤 프로세스의 전산화에 관한 것이고, 그것을 표현하는 최선의 방법의 폭이 꽤 적당하니까요. 그래서 코드가 영어(자연어)보다 구조적으로 더 빨리 안정화되는 것일 수도 있습니다.

의견 불일치 다루기 (Dealing with Disagreements) 빌 베너스: 『익스트림 프로그래밍(Extreme Programming Explained)』에서 켄트 벡은 "공동 소유권은 프로젝트에서 개인의 권한에 대한 느낌을 증대시킨다. 당신은 다른 누군가의 어리석음 때문에 곤란을 겪을 필요가 없다. 방해되는 것이 보이면, 그것을 치워버리면 된다."라고 썼습니다. 무엇이 '어리석은 것'인지에 대한 사람들의 생각이 충돌하면 어떻게 됩니까? 어리석음은 주관적인 판단 아닌가요?

워드 커닝햄: 네, 저는 그런 식으로 표현하지 않았을 겁니다. 제가 모든 논쟁에서 이길 필요가 없다는 것을 깨달았을 때가 제 프로그래밍 경력의 전환점이었습니다. 누군가와 코드에 대해 이야기하다가 제가 "A 방식이 제일 좋은 것 같아요"라고 하면, 상대방은 "B 방식이 최선인 것 같은데요"라고 합니다. 제가 "아니요, 정말 A가 맞아요"라고 해도, 그들은 "음, 우리는 B로 하고 싶어요"라고 하죠.

제가 "좋아요. B로 하죠. 제가 틀렸어도 우리에게 큰 해가 되진 않을 겁니다. 제가 옳고 당신이 B로 해도 큰 피해는 없을 거예요. 왜냐하면 우리는 실수를 고칠 수 있으니까요. 그러니 그게 실수인지 한번 알아봅시다."라고 말할 수 있게 된 것이 전환점이었습니다.

우리는 미래를 예측해야 하는 점쟁이가 되려고 해서는 안 됩니다. 차라리 B를 시도해보고 무슨 일이 일어나는지 볼 수 있는 환경을 만드는 게 낫습니다. 사실 그 차이가 별로 중요하지 않을 때가 많습니다. 누가 프로그래밍하든 자신이 선택한 방식대로 할 자유가 있고, 그것으로 충분합니다. 물론 때로는 결과가 중요할 때도 있습니다. 다른 작업을 하다가 보니 "이건 B 방식 때문에 제대로 맞지 않네"라고 할 수 있죠. 이 문제가 제가 A를 주장할 때 생각했던 것일 수도 있고 아닐 수도 있습니다. 개발자가 B의 맥락 안에서 억지로 끼워 넣었을 수도 있죠. 그러다 보면 버그가 생기거나 개선이 어려워집니다. 그러면 개발자가 "이 코드 작업하는 거 지겨워 죽겠네"라고 합니다. 그때 제가 "저기, 그 버그 제가 맡을게요"라고 말합니다. 그들이 "정말요?"라고 하면, 저는 "그럼요, 제가 맡죠. 당신이 B로 했으니 저도 B로 작업할게요"라고 합니다. 그래서 제가 들어가서 작업하고, B 방식 중 쓸만한 부분은 최대한 활용하려고 노력합니다. 하지만 책임을 맡음으로써, 저는 그것이 필요한 기능을 수행하도록 만들 기회를 얻게 됩니다.

빌 베너스: A로 돌아간다는 말씀이신가요?

워드 커닝햄: 필요하다면요.

빌 베너스: 아니면 아마도 C로 가거나요.

워드 커닝햄: 보통은 C가 되는 경우가 많습니다. 우리 둘 다에게 배움의 경험이 되는 거죠. 경험 없이 결정만 한다면 우리 중 누구도 진정으로 배우지 못합니다. 워드가 이겼고, 다른 누군가는 졌거나, 그 반대겠죠. 그건 너무 소모적인 싸움입니다. 차라리 "일단 코딩해보고 무슨 일이 일어나는지 보자. 작동하지 않으면 바꾸면 된다"라고 말하는 게 낫지 않을까요?

중요하지 않은 결정에 대해 걱정하느라 얼마나 많은 시간을 소비하는지 말로 다 할 수 없습니다. 그냥 결정을 내리고 결과를 지켜볼 수 있다는 것은 엄청난 힘을 줍니다. 하지만 그러려면 무언가 잘못되었을 때 고칠 수 있는 환경을 마련해야 합니다. 무언가 잘못되었을 때 당신이나 고객에게 터무니없는 비용이 들어서는 안 됩니다. 말도 안 되게 비싸면 안 되죠. 실수를 감당할 수 없는 상황에서는 올바른 일을 하기가 매우 어렵습니다. 따라서 올바른 일을 하려고 한다면, 무엇이 옳은지 추측하기보다는 실수를 저지르는 비용을 제거하는 것이 올바른 방법일 수 있습니다.

예를 들어, 한 프로젝트에서 우리는 잦은 배포를 통해 실수 비용을 제거했습니다. 그리고 꽤 정교한 데이터베이스 스키마 진화(evolution) 메커니즘을 구축함으로써 그렇게 할 수 있었습니다. 우리는 매주 배포했고 매주 스키마를 변경했습니다. 고객마다 다른 순서로 다른 스키마 변경을 적용할 수 있었고, 결국에는 모두 통합되어 올바르게 작동했습니다. 매주 그렇게 했기 때문에 6~8주 후에는 우리가 해낼 수 있다는 믿음이 생겼습니다. 결코 두렵지 않았습니다.

대부분의 사람은 "무엇을 하든, 정말 어쩔 수 없는 경우가 아니면 스키마 변경은 하지 마세요"라고 말합니다. 그리고 프로젝트가 끝날 때쯤 "맙소사, 진짜 변경해야겠네"라고 하죠. 그래서 한 번도 해본 적 없이 "이왕 할 거면 한꺼번에 다 하자"라고 합니다. 그들은 경험도 없는 거대한 프로젝트를 벌입니다. 그리고 어떻게 될까요? 잘못됩니다. 반면에 우리는 매주 합니다. 매주 조금씩 하죠. 우리는 정말 능숙해집니다. 전혀 두렵지 않고 문제 될 게 없습니다.

우리는 문제를 지우려고 노력하는 대신, "이것이 우리가 하는 일의 본질이다"라고 말함으로써 문제를 없애버렸습니다. 그렇게 간단할 수 있다는 게 참 묘하죠. 이는 사실 "무엇을 잘하고 싶은가?"를 묻는 접근 방식에 가깝습니다. 잘하고 싶다면 매일 연습할 방법을 찾으세요. 매일 연습하면 잘하지 않을 수 없습니다. 그러니 당신이 잘하고 싶은 것을 고르세요. 음, 당신은 당신이 두려워하는 것을 잘해야 합니다. 그러면 더 이상 두렵지 않게 될 것입니다.

다음 주 12월 8일 월요일, 버트란드 마이어(Bertrand Meyer)와의 대담 첫 번째 편을 보러 오십시오. Artima.com의 새 기사 알림을 매주 이메일로 간단히 받아보고 싶으시면 Artima 뉴스레터를 구독하세요.