Archive for January, 2010
소프트웨어 공학의 사실과 오해 8 – 유지보수
유지보수
유지보수는 보통 소프트웨어 비용의 40~80%(평균 60%)를 차지한다. 따라서 유지보수는 소프트웨어 생명주기 중 가장 중요한 단계일 것이다.
p.209
몇 년 전에 신입사원을 가르치면서, “이렇게 하면 나중에 수정하기가 어려우니까 저렇게 하는게 좋다.”라는 식으로 얘기를 했더니 “팀장님은 나중에 수정하는 것을 굉장히 신경쓰시는 것 같아요.”라는 반응을 보였다. 내가 너무 당연하다고 생각하던 걸 신기하다는 듯이 얘기해서 어리둥절 했었는데, 그 때 이런 통계 자료가 있었다면 좋았을 걸.. 이라는 생각이 든다.
소프트웨 유지보수 비용에서 약 60%는 개선 작업에 쓰이는 비용이다. 오류 정정은 약 17% 정도다. 따라서, 소프트웨어 유지보수는 기존 소프트웨어를 보수만 하는 것이 아니라 새로운 기능을 추가할 때도 많다.
p.213
자, 60+17=77%다. 유지보수 비용의 나머지는 어디로 갔나? 18%는 환경이 변하더라도 소프트웨어가 계속 작동할 수 있도록 하는 적응성 유지보수(adaptive maintenance)라 불리는 것에 들어간다. -중략- 그런데 유지보수 비용의 나머지 5%는 뭘까? 이럴 때 항상 나오는 ‘기타’다. 여기에는 소프트웨어를 더욱 유지보수하기 편하게 만드는 작업도 포함된다. 이런 작업을 예전엔 예방적 유지보수(preventive maintenance)라 했고 최근에는 이런 활동을 표현하는데 리팩토링(Refactoring, Fowler 1999)이란 용어가 쓰인다.
p.214, 215
유지보수는 문제가 아니라 해결책이다. -중략- 유지보수는 “우리는 이런 것을 구축했지만 지금 보니 약간 다른 것을 구축했어야 한다.”와 같은 문제를 해결할 수 있는 유일한 방법이다.
p.217
유지보수는 귀찮은 문제를 해결하는 업무이고 그래서 안할수록 좋다라는 느낌이 있었는데, 사실은 신규 개발과 거의 차이가 없는 솔루션 개발 업무라는 것을 배웠다.
소프트웨어 유지보수 생명주기의 각 단계는 개발 생명주기와 거의 같다. 문제에 대한 요구사항을 분석하고, 수정 또는 개선 작업을 한다. 기존 시스템의 설계 컨텍스트 안에서 솔루션을 설계한다. 솔루션을 코딩하고 기존 시스템에 맞춰 넣는다. 코딩된 솔루션을 테스트하면서, 새로 변경한 것이 제대로 동작하는지, 예전에 제대로 작동하던 것들에 영향을 끼쳐 문제를 일으키지는 않는지 확인하다. 그리고 나서, 개선된 부분을 기존 시스템에 반영하고 계속 유지보수한다.
p.219
점진적인 개발 방식을 사용하면 지속적으로 작은 릴리즈를 하고 사용자의 피드백을 받아 개선하게 되니까, 점진적인 유지보수라고 부를 수도 있지 않을까? 처음에 돌고래 스몰토크를 써봤을 때 받은 인상도 비슷한데, 보통의 개발은 아무것도 없는 상태에서 기능을 생성해나가는 느낌이라면, 돌고래 스몰토크에서는 이미 잘 돌아가는 시스템을 리펙토링 해서 기능을 추가해나가는 느낌이었다.
하지만 유지보수 단계에서 “기존 시스템의 설계 컨텍스트 안에서 솔루션을 설계한다.”라는 것이 가장 큰 차이점인데 이는 생각보다 훨씬 어려운 작업이라고 한다. 그 이유는,
설계로 전환하는 시점에서 요구사항의 폭발적 증가, 대부분의 문제에서 설계 솔루션이 하나만 있는 것은 아니라는 사실, 설계는 복잡하고 반복적인 과정이라는 사실, 문제의 복잡성이 25% 증가하면 솔루션의 복잡성은 100% 증가한다는 사실. 이 모든 사실을 조합하면, 설계는 어렵고, 지적이며, 창조적인 작업이란 것을 알 수 있다. 여기서 말하려는 것은 역설계(undesign, 이미 구축된 시스템의 설계를 역공학으로 알아내는 것)라 부를만한 것으로, 이는 최소한 원래의 설계 작업만큼 복잡하다.
p.220
유지보수를 귀찮은 문제를 고치는 하찮은 작업으로 보기 쉽지만, 위의 증거들을 통해서 중요한 솔루션 개발 작업이며, 신규 개발에 필요한 것 이상의 높은 기술을 요구하는 작업이란 사실을 알 수 있다.
하지만 현실에서는 유지보수를 하찮은 작업으로 보는 경우가 많으므로 (담당자 스스로도!) 신입사원이나 경력이 적은 개발자에게 유지보수 업무를 맡기고, 실력이 좋은 개발자는 신규 개발에 투입되는 일이 흔하다. 그렇다보니 초기의 설계를 충분히 이해하지 못한 상태에서 코드의 수정이 이루어지고, 코드는 점점 더 엉망이 되어간다. 그러면 다시 새로운 시스템의 신규 개발이 시작되고 실력있는 사람들은 이 일에 투입된다. 기존에 유지보수를 하던 인력은 이 “실력있는 사람”들이 만든 또 다른 시스템을 유지보수 하게 된다. 불행하게도 여태까지의 내 경험과 일치하는 내용이다.
더 좋은 소프트웨어 공학 기술로 개발하면 더 많은(더 적은 게 아니라) 유지보수가 필요하다. -중략- 이런 시스템은 더 많은 수정이 가해지기 때문에 다른 시스템보다 더 오래 유지된다. 그리고 이런 잘 구축된 시스템은 개선하기가 쉽기 때문에 더 많은 수정이 가해진다.
p.226
이 사실은 “유지보수는 문제가 아니라 해결책이다.”라는 사실에 대한 흥미로운 예다. 유지보수 활동을 솔루션으로 본다면, 더 많은 작업을 할수록 좋다고 생각할 수 있다. 그러나 유지보수를 문제로 보는 시각에 묶여 있으면, 유지보수 활동이 늘어나는 것을 좋게 볼 수 있는 방법이 없다.
p.227
스크럼 일기 1 – 역할
새해가 되어 스크럼마스터와 새 스크럼을 구상하면서 그동안 잘못해오던 것들이 몇 가지 드러났다. 작년에도 많은 교훈을 얻었는데 적어두지 못한게 아쉽던 터라, 올 해는 같은 실수를 반복하지 않도록 잘 적어두기로 했다.
프로덕트 오우너와 개발팀의 역할을 명확하게 하고 그에 맞는 정보를 줘야 한다.
좀 당연한 얘기라서 쑥스럽지만 ^^;; 일단 프로덕트 오우너(이하 오우너)란 우리말로는 “제품 책임자”. 제품의 스펙을 결정하고, 스펙 중에 우선순위를 결정해주는 사람이다. 개발팀은 당연히 제품 책임자에게 요청받은 스펙을 구현하는 사람들.
역할을 명확하게 하는 것이란?
다른 말로는 “책임”과 “권한”을 명확하게 하는 것. 예를 들면 아래와 같이,
- 오우너는 개발팀에게 A라는 스펙을 주고 구현할 책임을 준다
- 개발팀은 A라는 스펙을 어떻게 구현할지 결정할 권한을 갖는다
역할이 명확하지 않은 경우에 발생하는 현상
- 개발팀이 책임 이상의 것을 하거나, 요청받는 경우
- 개발팀이 A라는 스펙이 올바른 것인지 고민하고 있다
- 개발팀에게 A라는 스펙을 올바르게 수정하기를 요구한다
- 오우너가 책임 이상의 것을 하거나, 요청받는 경우
- 오우너가 구현 방법에 대해 일일이 관여한다
- 오우너에게 구현방법에 대해서 일일이 물어본다
- 책임이나 권한이 있는 것 같은데, 막상 정보가 부족하다
- 개발팀이 A라는 스펙을 개선하기에는 프로젝트의 비전, 사업 우선순위에 대한 정보가 부족하다.
해결책은?
- 개발팀이 A라는 스펙이 올바른가 고민하지 않기를 바란다면, 그 사실을 명확히 하고 합의한다.
- 개발팀이 일정부분 스펙을 수정해주기를 바란다면, 그 사실을 명확히 하고 필요한 정보를 준다.
- (위 그림의 파란박스에서)개발팀이 어느 높이까지 책임과 권한을 갖는지 명확히 하고 합의한다.
- 개발팀의 역할을 수행하는데 필요한 프로젝트의 목표, 비전, 가치, 우선순위와 같은 정보 제공한다.
- 개발팀이 구현 방법에 대해서 오우너에게 물어본다면
- 역할을 명확하게 해서 개발팀 스스로 판단할 권한이 있음을 주지시킨다.
- 혹은 판단하기에 충분한 정보를 주지 않은 것은 아닌지 확인한다.
현실에서는 알아차리기 힘들 수 있다
“오우너가 스펙을, 개발팀이 구현을”. 설명을 쉽게하려고 이렇게 말했지만 좀 더 원칙적으로 얘기하면 “오우너가 더 추상적인 스펙을, 개발팀이 더 구체적인 스펙을”이 되어서 현실에서는 구분이 어려울 수 있다.
스펙이 “폰트를 바꾸는 기능 추가”와 같이 유저 관점의 기술(記述 description)인 경우에는 구분이 명확하지만, 스펙이 “3가지 DB 지원”과 같이 기술(技術 technology)적인 경우에는 헷갈리기 쉽다. 그래서 라이브러리나 미들웨어 같이 제품을 쓰는 사람도 개발자고, 만드는 사람도 개발자인 경우에는 스펙과 구현의 선을 명확히 긋고 역할을 합의하는 일이 중요한 것 같다.
마무리
오우너가 자꾸 이상한 일을 시킨다거나, 개발팀이 원하는 일을 해오지 않는다거나 하는 문제가 생겼을때는 각자의 자질을 의심하기 보다는 역할을 명확히 합의했는지 확인해 볼 일이다.
소프트웨어 공학의 사실과 오해 7 – 검토와 검사
검토와 검사
비약에 가까운 기법이 하나 있는데, 아이러니하게도 이 기법은 소프트웨어 오류 제거 활동에서 제외되어 한 구석에 처박혀 있다. 엄격한 검사가 그것으로, 소프트웨어에 포함된 오류를 찾기 위해 노력을 쏟는 이 기법은 거의 비약이라 할 수 있다. 연구 조사를 거듭한 결과 검사는 테스트 케이스를 실행시키기도 전에 소프트웨어 제품에 포함된 오류의 90%를 발견할 수 있다는 것이 밝혀졌다.
p.191
그런데도 불구하고 검토와 검사가 CASE 도구나 여러 방법론과 같은 더 못한 것들도 받던 찬사를 받지 못하는 이유는 아래의 4가지.
- 검사로 돈을 버는 메이저 벤더는 거의 없다.
- 검사에는 새로운 것도 없고 따라서 시장성도 없다.
- 검사는 소프트웨어 생명주기의 뒤쪽 단계에 있는 보이지 않는 부분으로 간주된다.
- 검사는 효율적이긴 하지만, 녹초가 될 정도로 정신을 집중해야 하는 고된 작업이다.
대부분의 방법론이나 프랙티스의 유행의 배경에는 해당 제품으로 돈을 버는 메이저 벤더가 있어왔다는 것이 이책의 일관된 주장이다. 실제로 은 탄환Silver Bullet이란 없기 때문에 애초에 유행할 것이 없지만, 과대선전자들에 의해 근거없는 유행이 생겨난다는 것.
제품의 출시후에 어떤 일이 있었는지 숙고하거나 앞으로 어떻게 개선할 수 있을지에 대해 기록하는 회고를 시행하는 조직이 거의 없다는 얘기에 이어서 아래의 내용이 나온다.
그 결과 소프트웨어 프로젝트에서 배운 모든 교훈은 버려지거나, 프로젝트가 끝날 때 바람과 함께 날아가 버린다. 왜 그럴까? 소프트웨어 분야의 광폭한 일정으로 인해, 어제 프로젝트에서 일하던 프로그래머들이 이미 내일 프로젝트로 흩어져 배치돼 버리기 때문이다. 그리고 거기서는 새로운 일정에 묶여 몇 달 전에 어떤 일이 있었는지 생각할 겨를도 없다.
p.200
결국 소프트웨어 분야는 한 자리에 처박혀 매 프로젝트마다 같은 실수를 반복하고 있고. 소프트웨어 분야의 지혜Wisdom는 증가하지 않는다는 얘기.
어떤 문제에 대한 올바른, 최적의 솔루션이 딱 하나만 있는 경우는 거의 없다고 했던 것을 상기하기 바란다. 솔루션을 검토할 때 다른 개발자가 선택한 방법의 관점에서 검토하는 것은 자신의 방법 관점에서 검토하는 것보다 어렵다. 다른 사람의 신발을 신고 먼 길을 걷는 것은 쉬운 일이 아니다.
p.205
동료 검토Peer Review에는 기술적 측면과 사회적 측면을 모두 중시해야 하는데, 위와 같이 기술적 검토 작업을 훌륭히 하는데 필요한 ‘집중’으로 인해 검토의 사회적 측면에 대한 주의가 감소한다고 한다.
엄격함을 달성하기 위한 집중 때문에 사회적 문제를 해결하기 위해 남겨둔 에너지까지 모두 소모돼 버린다. 따라서 검토기간 동안의 사회적 문제는 심각해질 수 있다. 비자아적 프로그래밍(egoless programming)을 부르짖지만, 우리는 대부분 자신이 작업하는 제품에 이성과 감정을 투영하게 되고, 이로 인해 다른 사람이 우리의 작업을 검토하면 쉽게 상처받는다. -중략- 모든 자아가 위태로워지고 사회적 방어 메커니즘이 감소한 상태에서, 사회학적 폭발을 초래하는 것은 그리 오래 걸리지 않는다.
p.206
동료 검토 하면서 얼굴 붉히는 경험은 다들 있을 것 같다. 잘 먹히는 해결책을 제시할 수 있으면 좋겠지만, 기술적 측면과 사회적 측면에 모두 주의를 기울여야 한다는 사실이라도 업계에 널리 퍼졌으면 좋겠다. 문제가 인식되면 해결책이 도출되는 것은 시간문제가 아닐까.
개인적으로는 저자 워크숍 방식을 코드 리뷰에 사용해보고 싶은 바램이 있다. (해보신 분 있으실지도)
IBM developerWorks – 저자 워크샵 (김창준님)http://www.ibm.com/developerworks/kr/library/dwclm/20081230/
소프트웨어 공학의 사실과 오해 6 – 테스트
테스트
연구에 따르면, 프로그래머가 모든 코드를 완전히 테스트했다고 말할 때, 보통 55~60%의 로직 경로만이 실제로 테스트된 것이라 한다. 이는 소프트웨어 제품의 복잡성을 반증하는 것이기도 하고, 소프트웨어를 작성한 사람조차도 그들이 작성한 것에 대해 완전히 이해하지 못함을 보이는 것이기도 하다.
p.172
여기서 알 수 있는 것은, 수많은 종류의 테스트 방법이 존재하지만 소프트웨어 제품의 복잡성 때문에 완벽한 테스트는 불가능하다는 것이다. 이 때문에 (1)테스트를 수행하는 데 있어 타협할 수 밖에 없고, 적절히 선택해 타협하는 것이 매우 중요하며, (2)대부분의 주요 소프트웨어 제품이 오류를 포함한 채 출시되는 것 또한 놀랄만한 일이 아니다(순진한 사람들만이 오류 없는 소프트웨어를 기대한다).
p.173
많은 소프트웨어 전문가들이 오류 없는 소프트웨어를 만드는 것이 가능하다고 주장하며 이를 달성하지 못한 회사나 조직을 비난하지만, 이번 사실에서 명확히 알 수 있듯이 그 영광된 목표는 단지 아주 작은 규모의 소프트웨어 프로젝트에서나 가능할 것이다. 이제, 오류 없는 소프트웨어란 불가능한 목표는 포기하고, 매우 심각한 오류가 없는 소프트웨어 제작과 같은, 좀더 현실적이고 실현 가능한 목표에 집중하는 것이 중요하다.
p.174
어느 정도 규모가 있는 C++ 프로젝트에 유닛테스트를 적용해본 것은 작년이 처음이었는데, 왜 55~60%의 로직 경로만이 테스트 되는지 이해할 수 있을 것 같다. 제품 수준의 코드에는 인자의 유효성 체크, 상태의 유효성 체크, 실패에 대한 체크 등으로 엄청나게 많은 분기가 발생하는데 이런 예외 상황을 완벽하게 테스트하는 것은 비용대비 효율이 떨어지기 때문이다. 높은 테스트 커버리지는 반드시 달성해야만 하는 목표라기 보다는, 프로젝트의 여러 목표 중에 하나가 되어서 우선도를 따져보는 것이 맞는 것 같다. 적당한 테스트 커버리지에 대해서는 지난 번 포스팅 어느 정도의 테스트 커버리지가 필요할까를 참조.
100%의 테스트 커버리지가 가능하다 하더라도, 이는 충분한 테스트 기준이 아니다. 대략 소프트웨어 결함의 35%는 누락된 로직 경로에서, 40%는 로직 경로의 특정 조합을 실행할 때 나타난다. 이런 것들은 100% 커버리지로도 잡히지 않을 것이다.
p.176
100%의 구조적 커버리지가 발견할 수 있는 것은 단지 25%의 오류라는 의미다. 저자가 가진 오류 데이타베이스로부터 산출한 비율이라는 점도 감안하자.
소프트웨어 테스트 도구가 널리 사용되지 않는 데는 세 가지 주요 요인이 있다. 1. 소프트웨어 분야의 경영진과 학계는 모두 앞쪽 단계를 훨씬 더 중요하게 보이도록 만들었다. -중략- 2. 뒤쪽 단계의 작업은 기술적으로 너저분하다. -중략- 3. 생명주기의 뒤쪽 단계에는 일정 압박이 심하다. -중략-
p.181, 182
소프트웨어 업계는 요구분석, 설계, 구현을 지나서 테스트에 대한 관심이 높아지고 있는 것 같다. 앞쪽의 단계에서 은 탄환Siver Bullet을 찾지 못해서 자꾸만 뒤쪽 단계에서 기회를 찾으려 이동한다는 얘기도 있지만, 소프트웨어 분야의 모든 행위에 대해서 한 번씩 조명을 하고, 쓸데없는 미신이나 착각, 오해를 없앨 수 있었으면 하는 바램이다.
평화로운 전사
"'마음'이란 안절부절 못하는 정신의 가짜 투영이야. 그것은 잠재의식에서 표면으로 떠오르는, 통제되지 않는 닥치는 대로의 모든 생각을 포함하고 있네. 의식이 마음은 아냐. 자각도 마음은 아냐. 주의력도 마음은 아냐. 마음은 장애물이야. 상태를 악화시키는. 그것은 일종의 인류 진화상의 실수라고 할 수 있네. 인간사의 근본적인 약점이야. 마음은 아무 쓸모가 없어." -중략- 그러나 수학 문제나 전화번호를 생각하는 걸 멈출 수 없을 때, 또는 자네가 의도하지 않았는데도 괴로운 생각이나 기억들이 떠오를 때는 자네의 두뇌가 일하는 것이 아니라 마음이 방황하는 거라네. p.78, 79
"이게 핵심이야. 명상은 두 개의 과정이 동시에 이뤄지지. 하나는 통찰. 이는 일어나는 것에 주의를 기울인다는 뜻이야. 나머지는 항복. 일어나는 생각에 대한 집착을 놓아 버리는 것이지. 이렇게 해서 마음에서 벗어나는 거라네." p.113
"절제? 그건 수준 이하요, 두려움이고, 혼란을 숨기는 것에 불과해. 악마의 딜레마지. 하는 것도 아니고 안 하는 것도 아냐. 아무도 행복하게 해 줄 수 없는, 비틀거리는 타협일 뿐이야. 절제는 무미건조하고 변명을 일삼는 이들, 증언대에 서기 두려워 주변부에만 머무는 사람들을 위한 거지. 그건 웃거나 우는 걸 겁내는 사람들, 살거나 죽는 걸 겁내는 이들의 몫이야. 절제란 악마가 직접 달인, '미적지근한 차'라고!" p.166, 167
"과거를 바꾸기 위해 자네가 할 수 있는 건 아무것도 없어. 그리고 자네가 기대하거나 원하는 대로 미래가 딱 맞춰서 오진 않을 거네. 전사는 과거에도 없었고 미래에도 없을 걸세. 전사는 지금, 여기 있네. 슬픔이나 두려움, 분노, 후회 그리고 죄책감, 자네가 부러워하는 것이나 앞으로의 계획이나 갈망은 모두 과거나 미래에 존재한다네." p.214
"바보는 욕망이 채워지면 '행복'하지만, 전사는 아무 이유 없이 행복하다네. 그래서 행복이 궁극의 훈련이 되는 거라네. 행복은 내가 가르쳐 준 그 모든 것 위에 있어. 행복은 단지 자네가 느낄 수 있는 그 무언가가 아냐. 그건 자네 그 자체라네." p.247
찾을 필요가 없다. 성취란 아무 곳에도 데려다 주지 않는다. 아무 차이가 없으니 지금 그저 행복하라! 모두 하나이기 때문에 사랑은 이 세상의 유일한 실재이다. 그리고 유일한 법이라면 역설, 유머 그리고 변화다. 아무 문제도 없고 없어 왔고 앞으로도 결코 없을 것이다. 당신의 싸움을 놓아 버리고, 마음을 내버려 두라. 걱정을 멀리 던지고 세상 속에서 편히 쉬라. 삶에 저항할 필요가 없으니 그저 최선을 다하라. 눈을 뜨고 각자 생각했던 것 이상인 자신을 바라보라. 당신이 세상이고 당신이 우주다. 당신은 당신 자신이자 그 밖의 모든 이들이기도 하다! 이 모두가 신의 놀라운 각본이다. 일어나라, 일어나 유머 감각을 되찾으라. 걱정 말라, 당신은 이미 자유롭다! p.257, 258


