[Code Complete 2] 소프트웨어에 선행 조건

Date:     Updated:

카테고리:

태그:

품질이 좋은 소프트웨어를 개발하는 개발자들은 공통적으로 자신만의 고급 실천법이 있습니다. 그러한 실천법은 프로젝트의 시작과 중간, 끝 단계에서 품질을 중요시 한다는 것입니다.

이번 포스팅에서는 프로젝트 시작에서 품질을 위해 할 수 있는 여러가지 방법들에 대해서 이야기 합니다.

프로젝트 선행 조건

소프트웨어를 개발하다보면 개발 사이클 중 코드를 짜며 구현을 하는 기간이 약 65%라고 합니다. 이러한 수치만을 보고 몇몇 개발자들은 구현에만 초점을 맞추고 개발을 하는 경우가 있습니다.

하지만 이것은 잘못된 생각입니다. 1970년대 이후로 소프트웨어 개발 주기에 대한 많은 연구가 있었지만, 거기에 나온 자료를 보면 본격적으로 구현을 시작하기 전에 적절한 준비작업을 수행했을 경우 프로젝트를 가장 훌륭하게 진행할 수 있었다는 점을 알 수 있습니다.

이는 준비 작업에서의 위험 축소를 통해 잠재적인 리스크들을 제거하려는 노력을 하기 때문입니다. 여기서 위험 축소란, 소프트웨어가 고객의 생각과 다르게 개발되는 점을 방지하고, 고객의 불충분한 요구사항들을 더 확실하게 정의 하는것 등 불확실한 요소들을 제거하는 것을 말합니다. 따라서 위험 축소단계에서는 고객이 진정으로 원하는 것이 무엇인지 알아내기 위해서 생각보다 많은 노력을 들여야 합니다. 그 많은 노력을 들이는 비용이 잘못된 프로그램을 만들어서 쓰레기통에 버리고 처음부터 다시 만드는 것보다 비용이 싸기 때문입니다. 실제로, 이러한 노력을 거친 프로젝트는 그렇지 못한 프로젝트보다 적게는 10배, 많게는 100배까지 비용이 적게 든다는 통계도 있습니다.

현실적인 선행조건

위 글에 따르면, 선행조건을 반드시 완벽하게 구상하여 프로젝트를 시작하는게 좋아보입니다. 하지만 저것은 이론치 이며, 실제로는 선행조건은 100% 완벽하게 구상하여 프로젝트를 시작하기란 쉽지 않습니다. 현실에서는 시간, 비용, 고객의 지식 수준, 프로그래머의 기술력 등 많은 변수들이 작용하기 때문입니다.

따라서 저자는 파레토 법칙에 기반한 선행조건 구상을 제시합니다. 파레토 법칙은 천체 결과의 약 80%가 전체 원인의 약 20%에서 발생한다는 법칙 입니다. 이걸 소프트웨어에 적용하면, 요구사항 중에서 80%정도를 미리 명시하고 추가적으로 기술할 시간을 할당해둔 다음, 프로젝트를 진행하면서 가장 중요하다고 생각되는 새로운 요구사항들만 수용할 수 있도록 실제 구조 변화를 꾀하는 것입니다.

다른 방법으로는 요구사항의 20%정도만 명시한 다음 프로젝트를 진행해 나가면서 추가적인 요구사항과 설계를 기술 할 수 있습니다.

즉, 여기서 알 수 있는 점은 프로젝트에 따라 선행조건을 구상하는 방법을 다르게 적용할 필요가 있다는 것입니다. 어떤 프로젝트에서는 선행조건에 시간을 거의 할애하지 않아서 구현 시 불필요한 변경이 매우 많고 결과적으로 프로젝트를 일정대로 진행하는 데 차질이 생깁니다. 또 어떤 프로젝트는 선행조건에 너무 많은 시간을 투자해 나중에 쓸모 없다고 밝혀진 요구사항과 계획을 너무 고집해 결국 구현 과정에서 작업이 지연될 수 있습니다. 프로젝트의 성격에 맞게 선행조건 구상의 비율을 조절하는것이 시니어의 역량이라고 할 수 있겠습니다.

문제-정의 선행조건

선행조건, 아니 소프트웨어 에서 가장 중요한 시사점은 고객의 어떤 문제를 해결할 것인가? 입니다. 고객이 겪는 문제가 없다면, 굳이 돈을 내고 소프트웨어 개발을 의뢰하지 않을 것이기 때문입니다. 따라서 문제를 정의하는 것은 소프트웨어 개발의 본질이자 선행조건의 본질이라고 할 수 있습니다. 따라서 고객의 문제를 명확히 정의하고 거기에 따른 해결책을 제시하는것이 중요합니다.

하지만, 개발자들의 문제점이 여기서 나타날 수 있습니다. 그것은 개발로 모든것을 해결하려고 한다 입니다. 어떤 유튜브에서 그런 내용을 본 적이 있습니다. 어떤 엘리베이터를 12시 이후로 작동하지 못하도록 하는 요구사항을 받았다고 합니다. 그 요구사항을 받은 개발자는 엘리베이터를 12시 이후로 움직이지 못하게 하기 위해서 엘리베이터를 멈추고, 몇시간동안 코딩을 하여 그 문제를 해결했다고 합니다. 하지만, 같은 문제를 만난 시니어 개발자는 그냥 12시 이후에 엘리베이터 앞에 진입금지! 라는 표지판을 세워 문제를 해결했다고 합니다.

물론, 12시 이후로 표지판을 세워 통행을 막는것은 노동력이 들어가고 귀찮은 일일 수 있습니다. 하지만 위 이야기에서 시사하는 점은 꼭 개발만이 문제의 해결이 아닐 수 있다는 것입니다. 문제를 자세히 파악하고 비용을 줄일 수 있는 부분은 비용을 줄이며 효율적으로 문제를 해결하는 것이 중요하다고 할 수 있습니다.

요구사항을 명시적으로 기술하기

소프트웨어 개발을 하면 요구사항을 구두로 이야기 하고, 그것을 문서화 하게 됩니다. 구두로만 요구사항을 이야기하면 고객이 소프트웨어 개발 도중에 다른 이야기를 할 수 있습니다. 따라서 요구사항을 문서화하여 명확하게 근거를 제시할 수 있게 하는 것이 중요합니다. 일반적으로 개발자가 개발을 하며 전체 요구사항의 25%정도 변경을 요구하는 것을 경험하게 된다고 합니다. 이것이 일반적으로 소프트웨어 개발이 힘들어지고 재작업 하는 이유의 70%~85% 를 차지하게 됩니다.

물론, 변경이 너무 잦거나, 너무 많은것을 바꾸길 원하거나, 내용이 현실 가능성이 없을 때에는 프로젝트를 드랍하는것이 맞겠지만, 그것 역시 문서화된 요구사항에서 근거를 찾아야 하기 때문에 사소한 것이라도 문서화를 해서 서로 생각하는 것이 같은지 확인하는 작업이 반드시 필요합니다.

선행조건을 바탕으로 설계한 아키텍처

이번 장은 아키텍처에 대한 내용은 아니지만, 좋은 내용이 있어 요약합니다.

아키텍처라고 하면 전체적으로 클래스들끼리 어떻게 통신할지에 대한 규격이며, 더 나아가 요구사항 및 변경사항을 효율적으로 반영하며 확장하기 쉬운 구조를 만드는 것을 목표로 합니다.

따라서, 아키텍처는 잘 정의된 요구사항에 따라서 그 요구사항을 잘 처리하기 위해 짜여져야 합니다. 즉, 잘 짜여진 아키텍처는 봤을 때 감동적일 만큼 해결책이 자연스럽고 쉬워 보여야 합니다. 문제와 아키텍처를 포장용 테이프로 억지로 붙여놓은 것처럼 보여서는 안됩니다.

또한, 아키텍처는 모든 주요 결정사항에 대한 동기를 기술해야 합니다. 항상 그래왔다라는 식으로 정당화 해서는 안됩니다. 예를들어, 확장성을 위해 A 아키텍처만을 사용하는 개발자가, 확장이 필요없어 보이는 문제를 만났는데도 A 아키텍처를 사용하며 항상 그래왔다라고 이야기하면 그것은 A 아키텍처에 대한 이해가 없을 확률이 높을 뿐더러 일어나지 않을 일을 고려하였기 때문에 프로젝트 비용이 증가한다는 것을 시사할 수 있습니다. 따라서 프로젝트의 요구사항에 맞는 아키텍처를 사용해야 합니다.

끝으로, 아키텍처에 대한 확신이 있어야 합니다. 즉, 남에게 내가 얼마나 똑똑한가를 보여주려 하지 않아야 하고, 어려운 내용이 들어가서도 안됩니다. 실제로 구현할 사람(본인)이 이해하고 확신할 수 있는 아키텍처를 사용해야 합니다.

본인의 경험

외주 개발을 총 두 번 정도 경험했는데, 그중 제가 혼자 처음부터 끝까지 맡았던 프로젝트가 특히 기억에 남습니다. 바로 모션 인식 지휘 프로그램이었습니다. 지휘봉을 흔들면 센서를 통해 데이터를 전달받고, 그 값에 따라 음악이 빨라지거나(템포), 커지도록(볼륨) 재생되는 구조였습니다.

의뢰해주신 분은 하드웨어 쪽 전문가였지만, 소프트웨어 개발 경험도 없고 외주를 맡겨본 적도 없는 분이었습니다. 그래서 프로젝트 초기 요구사항을 정의하는 과정이 굉장히 어려웠습니다. 개발자인 입장에서는 너무 당연한 것들이 상대방에게는 전혀 당연하지 않았기 때문입니다. 예를 들어, 재생 버튼을 눌렀을 때 어떤 흐름으로 동작하는지, 지휘봉의 움직임을 어떤 공식으로 계산할 것인지, 블루투스는 어떤 규격을 사용할 것인지부터 일일이 설명하고 조율해야 했습니다.

다행히 요구사항이 자주 바뀌지는 않았지만, 프로젝트 마감 하루 전날에 지휘봉의 움직임을 처리하는 핵심 로직을 수정해달라는 요청이 들어왔습니다. 어쩔 수 없이 일정을 3일 더 연장해서 수정했지만, 그 과정은 정말 쉽지 않았습니다.

이 경험을 통해 몇 가지 중요한 교훈을 얻었습니다. 첫째, 요구사항은 초반에 최대한 명확하게 정의해야 한다는 점입니다. 둘째, 요구사항이 변경될 경우 비용과 일정, 소통 방식을 미리 합의해두는 것이 필수입니다. 셋째, 변경될 가능성이 있는 영역은 추상화와 확장성을 고려해서 구조를 설계해야 한다는 점도 깨달았습니다.

힘든 순간도 있었지만, 돌이켜보면 정말 값진 경험이었습니다. 개발 실력뿐 아니라 소통, 구조 설계, 일정 관리까지 짧은 시간에 크게 성장할 수 있었던 프로젝트였습니다.

Code Complete 카테고리 내 다른 글 보러가기

댓글 남기기