우리는 늘 고객이 우리의 개발에 참여해야 한다라고 말합니다. 그러나 실제 우리는 어떻게 그들을 참여 시키고 있습니까? 단순히 매주 한번씩 고객과 만나는 것인가요? 아니면 제품 출시 직전에 테스트를 통해 고객과 만나나요?
최근 The lean startup으로 유명한 Eric Rise는 Nordstrom이란 Team이 벌인 Flash build라는 개발 방식에 대해 글을 올렸습니다. 이들의 실험은 지금 무언가 마땅한 제품을 기획을 해내지 못하고 있는 회사나 조직이 반드시 해보기를 권하는 일입니다.
먼저 이들의 프로젝트는 ‘1주일간 선글라스 가게에서 사용할 앱 만들기'입니다. 이게 어떻게 가능할까요? 한번 생각해보세요, 여러분이라면 어떻게 할지.
이들의 방법은 이랬습니다. '우리 모두 선글라스 가게로 가자’. 개발팀, UX Designer등 모든 팀원들이 다들 선글라스 가게로 갔습니다. 그리고 한쪽 구석에 책상가져오고 Macintosh를 설치했습니다. 그리고 선글라스 가게에 오는 손님들에게 물어봤습니다. 그러면서 Prototype을 만들어갔습니다. 실제 구동하는 소프트웨어도 만들고 Paper prototype도 고객에게 보여주면서 수정해갔습니다. 결과는 아주 놀라웠습니다. 이들이 만들어낸 App자체보다는 이렇게 하면서 새롭게 알아난 것들이 아주 놀라웠습니다.
- 편광 선글라스 때문에 Portrait에서 Landscape로 바꿨다. : 원래 이 프로그램은 Portrait방식으로 개발되었었습니다. 손거울처럼 iPad를 쓰게 하자는 거였기 때문입니다. 하지만 선글라스 중에 편광 선글라스가 있습니다. 이것들은 가로 방향으로 아주 촘촘한 보이지 않는 선들을 코팅해서 그려놓은 것들인데 iPad의 액정 방식 때문인지 Portrait로 두면 아예 화면이 안보이는 것입니다. Nordstorm은 이 사실을 약 3일째 될 때 알았습니다. 급하게 수정이 들어갔습니다. 이건 직접 고객이 선글라스 끼고 보지 않았다면 AppStore에서 다운로드가 시작 되고서야 알았겠지요.
-단순 비교에서 시작했지만 줌기능을 넣어 두 장의 영상을 서로 비교할 수 있게 해줬다. : 이런 UX의 변화는 보통은 바로 얻기 힘듭니다. 고객이 참여해야만 얻을 수 있는 것입니다. 첨에는 단순히 비교만으로도 충분해 보였지만 서서히 사용자가 참여하면서 하나하나 필요한 것이 보이는 법이지요.
- 1주일의 Time Boxing : 생각해 보세요, 만약에 전체 프로젝트를 이렇게 한다고 하면 매우 많은 에너지를 써야 해서 지칠것입니다. 하지만 1주일만 이렇게 한다면 집중할 수 있습니다.
- 지금 고객이 있는 곳에 개발팀을 모두 데리고 가서 관찰하자. - 그 자리에서 고객에게 보여줄 수 있는 것이 있다면 보여주고 물어보자. - 짧게, 그러나 자주해야 한다.
정말 우리가 지금 이 순간 무엇을 해야 할지 모르는 팀이라면 이렇게 해보시기 바랍니다. 고객을 관찰하고 그들에게 질문하다 보면 많은 것을 얻을 수 있을 것입니다. 다음주 저희의 할 일을 알게 되었네요.
Eric Ries는 아래와 같이 흥미로운 것들을 찾아냈습니다.
1주일 단위 반복. 막판에 가서는 이 팀은 1주일 끝에서 끝마다 완전히 새로운 제품을 만들어 냈다.
달려가면서 스스로를 되돌아 보기를 계속했다.
간단하고 빠르고 실험적이다. 보통 iOS개발하면서 Rapid development 방식의 기술이 적용되기 힘들다. 그러나 이 팀은 2대의 iPad를 이용해서도 이를 극복했다. App이 개발되는 동안 Sales team은 하나의 iPad를 썼고 다른 팀은 다른 것을 썼다. 매번 개발이 끝날 때마다 Sales team은 이를 바꿔치기 했다. Paper prototype을 할 때도 똑같이.
우리나라에서는 정말 만나기 힘든 ‘Architect’이신 Joseph Yoder가 한국에 다른 일정으로 오셨습니다. 이분의 주무기는 Refactoring과 Adaptive Object Model, Design Pattern입니다. http://www.joeyoder.com/ 에 자세한 이야기가 나와 있습니다만 다양한 형태의 PLoP Conference를 주관하시고 있고 소프트웨어 아키텍쳐, 설계, 구현과 같은 다양한 소프트웨어 개발에 대한 훈련, 멘토링과 컨설팅을 하고 계십니다.
The Big ball of mud
특별히 이번에 진행된 Conference에서는 TDD와 Refactoring에 대한 이야기를 했습니다. 왜 소프트웨어는 가면 갈수록 점점 엉터리 코드로 엉망이 되어 가는걸까요? The big ball of mud pattern이란 이런 현상을 설명하는 좋은 예입니다. 동의어로 스파게티 코드가 있지요. 그런데 Joseph은 이러한 것이 반드시 나쁜 것이냐 라는 질문을 합니다. 이것은 “Worse is better” 라는 Gabriel이 1991년에 낸 생각과 유사합니다. 이 뜻은 “일찍 출시해서 시장이 최종 제품을 설계하는데 도움을 주게 하라"는 뜻인데 실제 오픈소스가 이런 방식으로 발전해왔지요.
즉 완벽한 소프트웨어를 만들기 위해 우리 모두 노력을 하지만 소프트웨어의 변화는 결국 진흙덩어리를 만들게 됩니다. 이것이 완벽히 없어야만 좋은 소프트웨어가 되는 것은 아니지만 이것을 계속 두게 되면 ‘기술의 빚'을 지게 되는 것이지요. 이것을 해결하는 방법으로 꾸준한 Refactoring, TDD등의 방법을 제안하고 있습니다.
그리고 이러한 소프트웨어의 변화는 계층에 따라 변하는 속도가 다르게 됩니다. 아래 순서대로 위쪽에 있는 것일 수록 늦게 변하고 아래로 갈수록 빠르게 변할 수 있다고 Footer와 Joseph은 주장을 합니다.
The platform
Infrastructure
Data schema
Standard frameworks and components
Abstract classes and interfaces
Classes
Code Faster
Data
Mud로 대표되는 소프트웨어의 문제점들에 대해 Joseph은 다음과 같은 주장을 합니다.
우리는 코드를 개량하고 복구하거나 개조해서 진흙덩어리들을 치워버릴 수 있다. (We can gentrify, rehabilitate, or make-over code helping clean up the mud.)
어떠한 패턴이나 프레임워크, 부분모듈, 그리고 객체가 오히려 진흙덩어리를 만들어 냈 다. 애자일 개발방식은 이를 해결하는데 도움을 주었다. (Even some patterns, framework, components, and objects works, helped with mud. Agile has helped some.)
Refactoring & TDD
이날 Joseph 굉장히 Refactoring에 대해 많은 시간을 가지고 소개했습니다. Refactoring의 정의, 종류, 위험도에 따른 분류까지 했습니다. 무엇보다 매일 그리고 점진적으로 Refactoring을 해나가야 한다라는 주장을 했습니다. 그리고 본인은 따로 Refactoring시간을 두지 않고 자연스럽게 하다보면 Refactoring을 하고 있더라라는 이야기를 했습니다.
그리고 이러한 Refactoring을 위해 Test를 꼭 하라면서 Testing이 Agile이 있기 전부터 Refactoring의 핵심원리라 할 만큼 강조했습니다. 저 역시 이 부분에 대해서는 정말 공감합니다. 그리고 TDD와 Refactoring이 서로 겹치는 부분이 있다 했습니다. 무엇보다 Test case를 먼저 안 썼다고 비난하지 말라 하시며 오히려 실제 구현 작성 하고나서 Test code를 작성하고 이것이 실패하면 구현을 수정하는 방식으로 일해도 된다했습니다. 저는 이 부분이 TDD관련되서 과거에 많이 논쟁이 되었던 것을 기억해보면 진짜 전문가는 ‘가지는 쳐내고 맥을 제대로 집는다'는 느낌을 가지게 되었습니다.
Refactoring & Design pattern
그럼 이러한 Refactoring을 할 때 구조를 바꿔야 하는 일도 있을 것입니다. Joseph 이때 Design pattern을 살펴보라고 했습니다. Design pattern이란 것이 실제 소프트웨어를 설계하면서 나온 일종의 공식이고 다른 사람들의 경험이 녹아 있기 때문이지요. 즉 Refactoring이 다소 복잡한 구조라면 이를 풀어나가는 방법을 생각하기 위해 Pattern catalogue같은 목록을 보면서 어찌 풀지 고민해 보라는 주장이었습니다. 물론 지나친 Pattern광신은 경계했고요. 그 후 PLoP에서 어떻게 패턴이 만들어지는지에 대해 소개해주었습니다. (Writer’s workshop같은 것들 )
Adaptive Object Model
추가적으로 AOP( http://adaptiveobjectmodel.com/ )에 대한 설명도 해주셨습니다. 이것도 Joseph 작품이거든요. 간단히 설명하자면 속성과 관계(Attribute and Relationship)에 대한 것들 / 그리고 행동(Behavior)을 객체로 분리해서 구현 하자는것입니다. 이렇게 해서 최대한 유연한 유로운 객체구조를 만들자라는것이 목적입니다. 이러한 설계가 나온 이유는 실제 현장에서 자주 구조를 재 설계해야 하는 일이 벌어지는 거죠. 예컨데 보험회사의 시스템의 경우 상품에 대한 구조가 바뀌는 것에 따라 이를 처리해주는 소프트웨어도 변해야 하는데 이를 단순히 상속기반의 설계로는 감당할 수 없습니다. 실제 Joseph이 이러한 설계를 생각해 낸 것도 금융 쪽 소프트웨어에 대한 설계를 하다 나온 것이라 했던것으로 기억합니다. (그렇게 들은 것 같은데 녹취록을 다시 들어보니 그런 말이 없어요.. T_T...) 자세한 구현은 http://www.codeproject.com/KB/architecture/AOMTypeObject.aspx 같은 것을 보시면 좋을 것입니다.
특히 이 분이 이 패턴을 설명하면서 ‘Over engineering’을 이야기 했는데, 이 패턴을 반드시 적용해야 하는 곳인지 잘 생각해서 하라는 의미였습니다. 유연한만큼 품이 많이 드는 패턴이기 때문입니다. ‘균형'을 잡으라는 뜻이죠.
재미있던 Q&A 시간
앞선 강의도 1시간을 좀 넘겼는데 이후 질문/답변은 무려 3시간을 지속했습니다. 배고프고 힘들어서 매실에이드와 녹차만 들이켰습니다... 많은 질문 답변 중에 몇개 골라서 적당히 요약해서 적어봅니다.
저는 개발할 때 Refactoring할 시간이 없었는데... : 지금 빚(Technical depth)을 갚을 것인지 나중에 갚을 것인지 문제입니다. 이것은 매일매일 되어야 하는 것입니다. 작은 것부터 해보시길 권합니다.
어떤 분들은 자신의 코드에 자신의 자아를 투영해서 심지어는 쓰레기임에도 남이 치우는 것을 싫어합니다. 이런 분들을 어떻게 다루거나 피해야 합니까? : 다른 분의 코드라도 코드를 정리해줘서 깨끗하게 유지하는 것은 좋은 일입니다. XP에서는 남의 코드, 내 코드의 구분하지 말라고 가르치지요. 혼자 할 때야 혼자의 코드이지만 팀을 이뤄서 일한다는 것은 내가 작성했어도 팀의 코드라는 뜻입니다. 함께 극복해야죠. 페어프로그래밍 방식을 도입해 보십시오. 각 부분(핵심, GUI등)팀들이 서로 돌아가면서 코드를 보게 하세요.
이런 상황에서 팀 리더가 아니라면 어떻게 해야 할까요? : 나쁜 방법은 코드리뷰를 할 때 , ‘이게 문제네요, 이게 뭐에요~’라면서 서로 놀리는 것입니다. 의외로 많이 이렇게 합니다. 이 문제에 대해 상대방을 배려하면서 ‘내가 이 부분이 이해가 안되는데 도와 줄 수 있어요?’라고 질문할 수 있어야 합니다. ( 저는 비폭력대화나 코칭을 배워보시길 추천합니다. )
타인의 코드를 Refactoring할 때 어떻게 진행하시나요? : 타인의 코드를 한번에 이해하기는 힘듭니다. 이럴 때 기존에 있는 큰 코드를 몇 개의 Procedure로 분해하고 이 Procedure의 의미를 물어보고 이름을 짓는 과정에서 자연스럽게 이해하게 됩니다. 마법은 없지요. 심지어는 디버거로 중단점 찍어가면서 확인도 합니다.
얼마나 Refactoring할 때 Comment를 남기나요? 어떤 사람들은 Comment없이 코드만으로 이해할 수 있게 짜라는 조언을 하는데요. : Kent Beck은 Comment가 길면 무언가 추상화 할 수 있는 잠재성이 있다고 했습니다. 어떤 사람은 Refactoring을 할 때 코드의 전체 구조를 먼저 Comment로 적고 실제 함수 이름은 그 Comment에서 띄어쓰기를 뺀 이름을 쓰기도 합니다. 어떻게 이름 짓는가가 어떻게 구현하느냐보다 중요하다고 Kent Beck은 이야기 했지요. Comment로 적어 놓는 다는 것은 어찌보면 이후에 제거해야 할 것들에 대해 표시를 하는 것과 같은 의미일 것입니다. ( 그러나 저는 Comment는 코드의 ‘의도'를 적어야 한다는 Code Complete의 저자인 Steve McConnell의 의견에 더 동의합니다.)
얼마나 하면 당신 같은 전문가가 될 수 있을 까요? : 매일 매일 노력해야 합니다. 작은 것이라도 개발환경을 개선하고 소프트웨어를 더 낫게 만들어야지요. 마법의 연차수는 없습니다. ^^ 스크럼 마스터 인증서가 실제 그 사람이 좋은 스크럼 마스터라는 것을 보증하지 않은데 검증없이 고용하는 회사들이 있죠. 실제 그 사람이 했던 결과물들, 코드를 봐야 합니다. Google이 이런 부분에 대해서는 잘 하고 있지요.
당신에게 지난 몇 년 동안 가장 도전적이었던 일은 어떤 것이었습니까? : 저에게 제일 힘든 문제는 소프트웨어 자체보다 사람들과 관계를 맺는 일이었습니다. 좋은 팀을 만드세요.
대부분의 경우 개발자들은 사람과 상호 작용을 다루는 일에 서투릅니다. 경영진은 사람과 친숙치 않은 사람과 일을 함께 하는데 서툽니다. 개발자들은 경영진이 쉽게 일을 생각한다 느끼고 경영진은 개발자들이 일을 성실하게 하지 않는다고 느낍니다. 그런데 정말 그것이 사실일까요?
왜 경영진은 개발팀이 보기에 촉박한 일정을 제시할까요? 경영진의 ‘욕구’를 생각해봅시다. 일반적인 경영에서는 제품의 출시로 매출이 나오면 성공이라 생각하지요. 그래서 빠르게 개발이 되어서 시장의 반응을 알고 싶어합니다. 또는 개발 기간 = 임금 비용이기 때문입니다. 즉 경영진에게 가치가 있는 일이란 가능한 적은 비용은 적게 들이고 빨리 시장에 물건을 내놓아 매출을 만드는 것입니다. 그리고 의외로 많은 시간을 고민고민해서 일정을 잡습니다. 이 점을 개발팀들이 잘 모르는 경우가 있습니다. (물론 지나치게 즉흥적인 제안을 들고오는 경우가 없다는 것은 아닙니다. )
개발팀의 욕구는 어떤 것일까요? 보통 일반적인 개발팀의 욕구는 ‘좋은 물건’입니다. 좋은 품질의 소프트웨어를 만들고자 하고 그것이 주는 기쁨을 매우 크게 생각합니다. 때로는 다른 모든 것을 희생하고라도 좋은 소프트웨어를 만드는데 힘을 쏟고 싶어합니다. 그리고 경영진이 생각하는 것 보다 실질적인 일정을 만들어낼 수 있는데 그 일을 하는데 제일 실질적인 정보를 가지고 있기 때문입니다. (물론 지나치게 일정을 늘려서 버퍼를 만드는 경우가 없다는 것은 아니지요. )
위에서 보듯이 경영진과 개발팀은 ‘제품출시’를 빼놓고서는 서로 욕구가 다릅니다. 그렇다면 어떻게 서로 대화를 이끌어가고 또 맞춰나갈까요?
우리는 서로 얼마나 이야기 하고 있나요.
자, 둘은 어떤 식으로 대화를 진행해야 할까요? 저는 몇 가지 체크리스트를 드리고 싶습니다.
계획을 세운 다음 그것이 유효했는지 스스로 물어볼 수 있는 회고와 같은 시간을 가지고 있습니까? 그것도 1주일 안쪽으로?
주어진 계획의 진행 상황을 관찰한 결과를 개발/경영 모두 정직하게 사실을 바라보고 있습니까? 두 조직 모두 같이 피드백을 주고 받습니까? 그 피드백에 대한 행동을 정해서 위험을 최소화 하는 노력을 했습니까?
우리가 만든 제품에 대해 고객이 정말 원하는 것인지 피드백을 정기적으로 받아보았습니까? 그 결과를 개발/경영 모두 정직하게 바라보고 있습니까?
요구사항이 변경 불가능한 시점에 대해 고객과 협의를 했습니까? (적어도 출시 2주 안쪽 ) 이에 대해 고객이 수긍하고 있습니까?
위에서 보듯이 사실상 경영진-고객-개발팀 이 세 이해당사자들이 모두 같이 그리고 함께 일을 진행해야 합니다. 그리고 세운 계획들이 제대로 돌아가는지 확인하고 위험 요소를 미리 분석하기 위한 노력을 기울여야 합니다. 세워진 계획이 얼마나 잘 돌아가는지 다시 피드백을 받고 점검하는 일에 대해 우리는 얼마나 힘을 쓰고 있나요?
애자일 프랙티스중 하나인 ‘반복계획’은 이런 문제를 해결하고자 만든 행동지침입니다. 보통 개발 계획을 잡으면 이런 식으로 많이 하죠.
계획회의1-> 계획회의2-> 계획 회의3-> 요구사항분석->개발->검증->출시
문제는 늘 요구사항 분석 뒤의 일들이 어떻게 돌아갈지 아무도 모른다는 점입니다. 출시가 되어야 고객은 뭔지 알아보는 경우가 있다는 거지요. 반복 계획은 이렇게 하는 겁니다.
1단계: 큰 것들에 대한 계획회의-> 요구 사항 분석-> 개발-> 검증->고객에게 출시
2단계: 1단계에서 알게된 것에 따라 계획 수정-> 요구 사항 수정/추가->개발-> 검증->고객에게 출시
3단계 부터 이후 : 2단에서 했던 방식을 고객의 요청과 수렴할 때까지 반복.
만약에 위의 단계에서 2단계 정도를 2주일 정도 약식으로라도 해보고 그 피드백을 근거로 개발팀이 일정을 추산한다면 경영진은 토를 달아서는 안됩니다. 실제 그것이 그 개발팀이 낼 수 있는 ‘최선’일 것입니다. 10년 걸려야 만리장성을 쌓을 수 있는데 위에서 ‘간절히 원하면 소원을 이뤄준다는’요정이 1년만에 쌓을 수 있게 해주지 않습니다. 대신 개발팀은 이렇게 이야기를 해야 겠지요.
“주어진 일정 XX개월 동안에는 이러이러한 기능까지 개발 할 수 있다. 일정을 더 주시면 어느정도까지 가능할 것이다.”
개발팀은 자신들이 내놓은 일정의 ‘근거’를 내놓는데 인색해서는 안될 것입니다.
제가 추천드리고 싶은 것은 일정은 한번 위에서 아래로, 다시 아래에서 위로 올리라는 것입니다. 그렇지 않은 일정은 대부분 공수표입니다. 지켜지지 않을 일정은 오히려 일할 의욕을 떨어뜨리고 경영진의 신뢰를 잃게 만듭니다. 일정을 가치있게 만들어야 하는 이유가 여기있습니다.
최악의 경우: 관리자가 무당이 될 때.
이때 제일 안좋은 상황은 ‘ 나쁜 관리’가 끼어드는 경우입니다. 지나친 조바심에 무조건 경영진의 입장을 강요하고 굴복시키려고만 하는 사람이 경영진과 개발자 사이에 끼어서 ‘관리’를 하는 경우를 말합니다. 그런데 이때 관리자들이 잊어버리는 것이 있습니다. ‘경영자가 약속 이행을 아무리 강하게 요구해도 진정으로 원하는 것은 결과물 자체’라는 점입니다. 그러므로 아무리 압박을 하더라도 그것이 결과물을 나오게 하지 못하거나 더디게 한다면 아무소용이 없다는 것입니다.
보통 자원이 부족하고 급한 상황이 벌어졌을 때, ‘합숙’같은 방법을 들고 나오는 관리자들이 있습니다. 같이 뭔가 모이면 뭔가 되지 않을까 싶은 ‘주술행위’지요. 만약에 테스트를 험하게 하기 위한 것이거나 구현 자체를 좀 집중적으로 하기에는 1주일 정도 괜찮을 수도 있지만 몇달이상 가거나 설계자체가 뒤죽박죽인 경우에는 오히려 문제가 더 커집니다. 이래서 피드백을 받고 이를 해석하는 시간이 필요하다는 겁니다. 방향이 틀릴 수가 있거든요.
의사소통이 우리를 구원했어요.
1986년 챌린저호가 폭파하는 사고가 벌어졌습니다. 출발한지 73초만에 공중분해되어 승무원 7명 전원이 사망했습니다. 물리학자인 리차드 파인먼이 이 사고의 조사를 담당했고 그 원인이 O-ring이 성층권에서 얼어버린 것이라고 밝혔습니다. 하지만 그보다 더 큰 원인은 NASA의 의사소통이라고 지적했습니다. 가장 말단에서 낸 우려가 위까지 전달안되서 생긴 사고란 것이었지요. 파인만은 여기서 지적하기를 “밑에서 낸 아이디어나 경고를 무시하는 순간 더이상 새로운 정보는 올라오지 못하게 된다"라 이야기를 했습니다. 경영진이 내는 일정은 보통 ‘출시’가 되야 하는 적기인 경우가 많습니다. 개발팀이 내는 일정은 ‘제대로 된 제품’이 나올 수 있는 시기인 경우가 많습니다. 경영진의 일정이 다소 짧다면 개발팀은 개발할 기능의 수를 줄이는 방식으로 재협의를 진행해야 할 것입니다. 만약에 경영진이 너무 짧은 일정밖에 줄 수 없는데 개발팀에서 거의 불가능하다는 판단이 나왔다면 서로 욕심을 부려서는 안됩니다.
일방적인 일정 강행이나 명령에 추종해서 어떤 중간 점검도 하지 않는 관리 문화가 가져다 주게 되는 폐해는 인류역사에서 충분히 많이 보았지만 많은 사람들은, 특히 군대문화의 신화를 가지고 있는 관리자일 수록 이를 따릅니다. 그리고 실패합니다. 제럴드 와인버그는 프로젝트의 실패 요인을 크게 두가지로 이야기 합니다.
행동 오류: 관리자의 비일치적인 행동때문에 일어나는 문제들
정보 오류: 주어지는 피드백에 오류가 있거나 잘못된 정보 때문에 생기는 문제들
혹시 우리는 개발 조직내에서 들려오는 목소리를 외면하지는 않습니까? 혹은 경영진의 요구사항을 '철부지들의 투쟁'이라 낙인찍고 들어보려고도 하지 않나요? 내일 아침, 출근해서 일정을 세우거나 추산해야 한다면 얼마나 정보를 가지고 있는지, 나의 결정이 내가 느끼는 것을 정말 제대로 반영하고 있는지 스스로에게 물어봐야 할 것입니다.