2020년 3월 15일 일요일

[Software Spec Series 8] 어떻게 소프트웨어를 빠르게 개발하는가?


소프트웨어는 빠르게 개발하는 것이 매우 중요하다. 소프트웨어 개발 기간이 오래 걸린다면 적절한 시장 진입 시기를 놓칠 수 있다. 소프트웨어 시장 변화는 매우 빨라서 너무 오래 개발을 하면 그동안 시장의 상황이 바뀐다. 경쟁자들은 새로운 제품을 출시하여 우리 회사에서 지금 개발하고 있는 제품이 뒤쳐지곤 한다. 또한 오랜 프로젝트는 개발자와 프로젝트 참여 인원들을 지치게 만든다. 이런 현상이 프로젝트를 더욱 더디게 한다. 프로젝트가 기간이 길어지면 그동안 새로운 요구사항이 추가될 가능성이 높다. 기획자는 변화하는 시장의 상황을 무시할 수가 없기 때문이다. 그래서 프로젝트는 더욱 늘어지고 품질은 떨어진다.

최근의 대부분의 개발 방법론들은 소프트웨어를 빠르게 개발하는 것을 중요시하고 있으며 회사에서도 소프트웨어를 빠르게 개발하기 위한 많은 노력을 들이고 있다. 그럼 어떻게 해야 소프트웨어를 빠르게 개발할 수 있을까? 소프트웨어를 빠르게 개발하기 위해서 고려해야 할 것은 매우 많지만, 여기서는 스펙 관점으로 살펴보려고 한다.

(느린 순차적 개발)


빌딩을 쌓을 때는 1층을 쌓고 2층을 쌓아야 한다. 1층을 쌓기 전에 2층을 쌓는 것은 불가능하다. 조립식 빌딩이라면 얘기가 다르지만 대부분의 빌딩은 순차적으로 쌓아 나간다. 소프트웨어도 이런 방식으로 순차적으로 개발을 해야 한다면 매우 오랜 시간이 걸릴 것이다. 거대한 소프트웨어는 수십년이 걸릴 수도 있다.

하지만 소프트웨어는 빌딩과 같이 1층이 완성되기를 기다렸다가 2층을 만들 필요가 없다. 1층과 2층의 인터페이스만 잘 정하면 따로 만들어서 합치면 된다. 다 만들어서 나중에 합치는 방법도 있지만, 1층과 2층의 뼈대만 만들어 놓고 동시에 만드는 방법을 더 많이 사용한다. 나중에 합치게 되면 합치는 과정에서 문제가 발생하기도 하지만, 처음부터 합쳐 놓고 동시에 만들면 합치는 과정에서 생기는 문제가 줄어든다.


(빠른 병행 개발 - 개발 후 통합)


(빠른 병행 개발 - 통합 후 개발)


이렇게 소프트웨어를 동시에 개발하여 프로젝트 기간을 단축하려면 분석, 설계가 잘 되어 있어야 한다. 특히 컴포넌트를 잘 나누고 인터페이스를 견고하게 정의해야 한다. 인터페이스는 간결하게 정의를 해야 각 모듈 간의 연동이 쉬워진다. 인터페이스는 확고하게 정의를 해야 하며 나중에 함부로 바꾸면 안된다. 물론 한번 정의한 인터페이스가 프로젝트 종료 시까지 변경되지 않으면 가장 좋겠지만 쉬운 일이 아니다. 개발 도중에 인터페이스를 변경하면 처음에 잘 정의한 경우보다 수십배의 변경 비용이 들어간다. 따라서 분석, 설계 시 최대한 노력을 하여 인터페이스가 가능하면 변경되지 않도록 정의를 해야 한다.

프로젝트가 크고 참여 인원이 많을수록 순차적인 개발보다 병렬 개발이 훨씬 좋다. 수십명의 개발자가 참여하는 프로젝트에서 순차적인 개발이란 거의 불가능하다. 수십명의 개발자가 처음부터 잘 통합된 소스코드를 기반으로 병렬로 개발을 해야 프로젝트를 빨리 끝낼 수 있다.


(순차개발과 병행개발의 개발 속도 차이 비교)


인터페이스는 상호간의 약속이다. 클라이언트와 서버 모듈을 병렬 개발할 때 인터페이스는 클라이언트 개발팀과 서버 개발팀의 약속이다. 인터페이스를 확정하면 서로 약속을 한 것이고 서로 헤어져서 따로 개발을 해도 문제가 없을 정도로 신뢰를 할 수 있어야 한다.

프로젝트 기간 내내 인터페이스를 잘 유지하기 위해서는 지속적인 통합이 필요하며 유닛 테스트, 테스트 자동화도 유용하다. 개발자는 자신이 작성한 모듈을 완성한 후에 소스코드관리시스템에 등록하는 것이 아니라 좀더 잦은 주기로 등록을 하여 프로젝트 주기 내내 소스코드가 정상적으로 빌드가 되도록 유지해야 한다. 너무 늦게 통합을 할 경우 많은 문제를 발생시키는 “통합의 지옥”을 맛보게 된다.

커밋은 하나의 기능이 완성이 되었을 때, 전체 클래스 또는 전체 컴포넌트를 모두 구현할 때까지 기다릴 필요가 없다. 하지만 항상 빌드는 되어야 한다. 또한 내가 소스코드를 수정하는 동안 다른 곳을 수정한 동료들의 소스코드와 머지(Merge)가 잘 되어서 제대로 빌드가 되는지 확인을 해야 한다. 보통은 적어도 하루에 한두 번 이상 커밋을 한다. 며칠씩 커밋을 하지 않고 지나가지는 않는다.

지속적인 통합을 위해서는 툴을 사용해도 되고, 직접 스크립트를 작성해서 구축을 해도 된다. 지속적인 통합을 도와주는 툴을 CI툴이라고 하며 Jenkins, Bamboo 등이 있다. CI툴 자체가 중요한 것은 아니지만 CI툴은 지속적인 통합을 조금 쉽게 해준다. 중요한 것은 지속적인 통합 활동을 성실히 하는 것이다.

지속적인 통합을 위해서는 주기적인 빌드가 필수다. Build on commit을 하기도 하고 Daily build를 하기도 한다. 밤에 빌드를 한다고 해서 Nightly build라고 하기도 한다. 프로젝트 기간 내내 Daily build는 실패가 없어야 한다. Daily build가 실패하면 인터페이스가 깨졌거나, 어떤 개발자가 깨진 소스코드를 올렸을 수 있다. 빌드가 깨지면 여러 개발자들이 개발에 차질을 빚게 된다. Daily build가 깨진 것을 브로큰 트리(Broken tree)라고 부르며 즉각 해결을 해야 한다.

거대한 시스템일수록 병렬 개발은 꼭 필요하다. 거대한 시스템의 구조를 얼마나 간결하게 하는지가 설계의 중요 요소다. Architect는 복잡한 시스템을 최대한 간결하고 복잡도를 줄여서 시스템의 개발, 유지보수 효율을 높여야 한다. 병렬 개발을 할 때 어려운 점은 내가 필요로 하는 컴포넌트가 아직 구현이 안되어 있어서 기능을 확인할 수 없다는 것이다.

예를 들어보자. 나는 사용자 관리 화면을 개발하고 있고 getUserList()라는 함수가 필요하다. 나는 사용자 목록을 출력하는 화면을 만들고 있는데 getUserList()를 개발하는 개발자는 아직 이 함수를 구현하지 않은 상태다. 그럼 나는 getUserList() 함수가 개발되기 전까지는 내가 만든 사용자 목록 화면을 테스트 해볼 수가 없다. 그럴 때는 getUserList() 함수에 가짜 코드를 추가하면 된다. 실제로는 DB에 쿼리를 해서 사용자 목록을 가져와야 하지만, 가짜로 Hard coding을 해서 사용자 목록을 넘겨주는 것이다. 물론 이런 가짜코드는 필요에 따라서 언제든지 넣고 뺄 수가 있어야 한다.

C언어로 개발을 한다면 다음과 같은 형태가 될 것이다. 아주 간단한 예를 든다.
#define USE_FAKE
RET getUserList(userdata *pData[], int &num)
{
#ifdef USEFAKE
  // make fake data
  num = 2;
  pData[0]->userid = 1;
  pData[0]->username = “John”;
  pData[1]->userid = 2;
  pData[1]->username = “Tom”;
#else
  // get data from database
#endif
  return RET_SUCCESS; 
}
(병행 개발을 위한 소스코드 예)

이와 비슷하게 개발 언어에 따라서 적절한 방법으로 병렬 개발하는 아이디어를 적용하면 된다. 병렬 개발을 위와 같이 각자 서로 다른 모듈을 개발하는 경우도 있고 하나의 모듈을 여러 개발자가 개발하는 경우도 있다.

잘 분석, 설계된 소프트웨어는 이와 같은 방법을 사용하여 병렬 개발을 진행하여 소프트웨어를 빨리 개발할 수 있다.

2020년 3월 1일 일요일

[Software Spec Series 7] SRS란 무엇인가?

소프트웨어 요구사항을 분석해서 작성하는 스펙 문서의 형태와 종류는 셀 수 없을 만큼 다양하다. 개발방법론에 따라서 제시하는 문서도 다르고 그 개수도 천차만별이다. 이 시리즈의 글에서 소개하고 주로 다룰 문서는 SRS다.

SRS는 Software Requirements Specification(s)의 약자다. Specification 혹은 Spec(스펙)이라고도 한다. SRS는 IEEE830에서 문서를 작성하는 가이드가 정의되어 있고, DoD(미국 국방부) 표준 문서이다.

SRS는 스펙 작성의 원리를 이해하는데 매우 유용하다. 어떠한 형태의 스펙 문서를 작성하더라도 스펙 작성의 원리를 이해하는 것은 매우 중요하다. 스펙을 작성할 때 생각하는 방법, 작성하는 프로세스, 포함되어야 할 내용, 각 내용에 대한 작성 가이드가 모두 포함되어 있다. SRS 역사는 오래 되었지만 스펙을 작성하는 원리는 지금도 변하지 않았다. 앞으로도 크게 변하지 않을 것이다. 그래서 SRS를 작성하는 원리를 깨우친다면 어떠한 방법론 하에서도 스펙을 잘 작성할 수 있을 것이다.

SRS는 IEEE에서 만든 표준 템플릿과 작성 가이드가 있다. 회사마다 조금씩 수정해서 자신의 회사에 맞는 템플릿을 별도로 가지고 있지만, 서로 매우 유사하여 SRS는 전세계 표준이라고 보면 된다. 소프트웨어 회사라면 각자 회사와 개발하는 제품의 특성에 맞게 커스터마이징 해서 사용하는 것이 좋다.

2020년 2월 16일 일요일

[Software Spec Series 6] 스펙과 프로젝트의 성공

스펙을 부실하게 작성하고 진행하는 프로젝트는 수없이 많다. 하지만 그 중에서 성공을 하는 프로젝트도 있다. 그래서 스펙을 제대로 작성했다고 착각을 하기도 하고 반대로 스펙을 제대로 작성해야 하다는 것을 믿지 않기도 한다. 이럴 때는 프로젝트가 10배로 커지고 개발자가 10배 투입되면 어떤 일이 벌어질지 상상을 해보면 된다.

많은 프로젝트들이 첫번째 버전을 성공했다가 이를 업그레이드하는 두번째 프로젝트에서 실패를 한다. 이를 “두번째 버전 신드롬”이라고 부른다. 첫번째 버전은 규모도 작고 적은 인원으로 진행을 해서 성공 확률이 높았지만 첫번째 제품의 성공을 기반으로 두번째 버전을 만들 때는 프로젝트의 규모가 커지면서 실패 확률이 확 높아진 것이다. 부실한 스펙 하에서 개집 만들기에 성공해 놓고 스스로 마천루를 개발할 수 있다고 착각하면 안된다.

스펙과 프로젝트 성공 확률의 상관관계를 아래 그래프로 살펴보자. 감을 잡기 위해서 개념을 설명하는 것이다. 숫자적인 의미를 부여하려는 것이 아니다. 프로젝트 성공과 관련된 수많은 요소가 있지만 그 중에서 스펙과의 관계만 살펴보자.


(프로젝트 규모와 프로젝트 성공확률과의 성관관계)


스펙을 부실하게 작성하면 프로젝트의 규모가 커지면서 프로젝트 성공 확률이 확 떨어지지만 스펙을 잘 작성하면 프로젝트의 규모가 커져도 프로젝트 성공 확률이 급격히 줄어들지 않는다.

2020년 2월 2일 일요일

[Software Spec Series 5] 스펙을 제대로 작성하지 않으면

소프트웨어를 개발하는데 있어서 꼭 알아야 할 규칙이 하나 있다. 바로 “1:10:100 rule"이다. 성숙한 개발 문화를 가지고 있는 회사는 전 직원들이 진정으로 그 의미를 알고 있고 실행하고 있다. 하지만 우리나라의 크고 작은 많은 소프트웨어 회사 임직원들은 그 의미를 모르거나 알고 있어도 단어의 의미로만 알고 있고 진정으로 깨우치고 있지는 못하다. 소프트웨어를 개발하면서 발생하는 많은 비효율과 문제들이 바로 여기서 출발하는 것이다.

그 1:10:100 rule을 설명한 그래프가 아래에 있다.

(스펙 1:10:100 규칙 그래프)

스펙을 작성할 때 요구사항을 바꾸면 “1"이라는 비용이 들지만 고객에게 전달된 다음에 바뀌면 수백배의 비용이 들어간다. 요구사항이든 설계든 한단계 뒤에서 고치게 될 경우 2~5배의 비용이 들어가서 단계를 거치고 시간이 흐를수록 수정 비용은 기하급수로 증가를 한다. 따라서 기획이 제대로 되어야 하고 분석 설계가 적절하게 잘되어야 한다. 한창 개발 중에 기획이 바뀌거나 요구사항이 바뀌면 그 수정 비용은 엄청나다는 것을 알아야 한다.

개발자들은 기획에서 정확한 요구사항을 주지 않는다거나 나중에 요구사항을 바꾼다고 불평이 많다. 불평은 하지만 그것을 현실로 받아들이고 스스로 이를 개선하려는 노력은 별로 하지 않는다. 오히려 상황이 그러니 분석, 설계를 제대로 하지 않고 대충 개발하다가 나중에 바꿔달라고 하면 또 대충 받아들여서 바꿔주고 이런 악순환을 반복하곤 한다.

기능에 따라서는 나중에 고쳐도 비용이 크지 않은 것도 있지만, 비용이 수백배 들어가는 것도 있다. 특히 아키텍처에 관련된 것이나, 비기능적인 요소는 나중에 수정할 경우 상상할 수 없는 비용이 들어간다.

이런 것을 극복하기 위해서 여러 방법론이 나오기도 하고 한때 Agile이 각광을 받았지만, 이런 방법론이나 기법으로는 이를 해결할 수는 없다. 정공법 외에는 방법이 없다. 기획을 제대로 하고 분석 설계를 효율적이고 적절하게 하면 된다. 또한 그 과정에서 모든 이해관계자가 책임을 지고 검토를 해서 문제가 없게 해야 하면 나중에 딴소리를 하거나 바꿔달라고 하면 안된다. 정말 중요한 변경 요청이 아니면 다음 버전으로 미루는 것이 좋은 전략이다.

2020년 1월 19일 일요일

[Software Spec Series 4] 스펙의 역할

소프트웨어 프로젝트에서 스펙의 역할을 알아보자.

모든 프로젝트 이해관계자가 사용, 프로젝트의 중심


스펙은 프로젝트의 모든 요구사항이 모이며 프로젝트의 중심이 되는 문서다. 프로젝트의 모든 이해관계자가 스펙을 참조하거나 작성에 참여한다. 스펙은 다시 여러 프로젝트 이해관계자들이 받아서 자신의 역할을 수행한다. 프로젝트에서 가장 중요한 문서 하나를 꼽으라고 하면 스펙이다.


(프로젝트의 모든 이해관계자가 참조해야 하는 SRS)


고객, 마케팅 부서, 영업 부서는 어떠한 제품이 만들어지는지 알 수 있다.


스펙이 없거나 부실한 상태로 진행하는 프로젝트는 프로젝트가 완료되기 전까지 어떠한 소프트웨어가 개발될지 알기가 어렵다. 그러면 영업부서는 소프트웨어 개발이 완료되기 이전에 판매 준비를 하거나 계약을 할 수가 없다. 스펙이 잘 작성된 프로젝트인 경우 스펙만 보고도 최종적으로 개발될 소프트웨어가 무엇인지 정확하게 알 수 있다. 영업부서에서는 이를 보고 판매에 필요한 준비를 할 수 있다. 영업망을 확충하거나 세일즈 자료를 준비할 수 있다. 또한 고객을 만나서 개발도 완료되지 않은 소프트웨어를 미리 팔 수도 있다. 소프트웨어 개발이 완료된 후에 부랴부랴 판매를 시작한다면 이미 상당한 판매 기회를 놓치게 된 것이다. 그 외에 안전, 의료, 보안 등의 인증이 필요한 경우도 스펙이 잘 작성되어 있다면 소프트웨어 개발이 완료되지 않았음에도 인증을 신청해서 인증을 미리 획득할 수 있다. 인증은 종류에 따라서 1년 넘게 또는 수년이 걸리기도 한다. 소프트웨어 개발이 완료된 후에서야 인증을 진행하면 수년의 영업 기회를 날려버릴 수도 있다.

프로젝트관리자(PM)에게는 스펙이 프로젝트 관리의 기준이 된다. 일정산정, 인력 배분, 리스크 분석 등을 할 수 있다.


스펙이 제대로 작성되지 않는 프로젝트에서 프로젝트 관리자는 별로 할 일이 없다. 일정을 제대로 예측하기도 어렵고, 리스크 파악도 어렵다. 적정한 리소스 계획을 세우지 못한다. 프로젝트가 진행이 되도 정확하게 진척률을 파악할 수가 없다. 그래서 1년짜리 프로젝트가 8개월쯤 지나도 정확하게 1년 안에 프로젝트가 종료될지 예측이 안된다. 그러면 프로젝트 관리자는 프로젝트 성공을 위해서 무엇을 더 해야 하는지 알 수 없다. 그저 운에 맡기는 수밖에 없다. 프로젝트의 성격에 따라서는 단계별로 진행을 하여 짧은 주기로 여러 차례 업그레이드를 하면서 진행하는 경우도 있다. 이 경우도 주기만 짧을 뿐이지 짧은 주기에 해당하는 스펙을 적절히 작성하는 것도 똑같이 필요하다.

개발팀은 스펙을 통해서 개발팀이 개발해야 할 제품이 무엇인지 정확하게 알 수 있다.


스펙을 제대로 작성하지 않았다면 개발팀은 정확하게 무엇을 개발해야 하는지 파악하기 어렵다. 기획자나 분석 아키텍트에게 너무 많은 것을 수시로 물어봐야 해서 시간을 매우 낭비해야 한다. 개발자가 임의대로 생각해서 기능을 구현하게 되면 기획의 의도와는 완전히 다르게 되기도 한다. 개발자에게 주어진 너무 높은 자유도가 소프트웨어 아키텍처를 부실하게 만들기도 한다. 개발자에게 자유도는 필요하지만 소프트웨어 전체 아키텍처는 분석, 설계 시에 정해져서 개발자에게는 한정된 자유도만 주어야 한다. 그래야 기획 시 의도된 소프트웨어가 제대로 개발될 수 있다.


(프로젝트에서 SRS의 위치)


테스트팀은 스펙을 통해서 테스트 계획 및 테스트 케이스를 작성할 수 있다.


보통은 스펙 작성 후에 개발자들이 구현을 하는 동안 테스트팀은 테스트 준비를 한다. 테스트 계획을 세우고 테스트 설계를 해야 한다. 하지만 스펙이 없거나 부실하다면 테스트팀은 테스트 준비를 제대로 할 수가 없다. 소프트웨어가 개발된 후에 소프트웨어를 보면서 테스트 준비를 해야 하는데 이 방법으로는 테스트 일정도 예측할 수 없고 부실한 테스트를 할 수 밖에 없다. 소프트웨어 품질이 나빠지는 것은 당연한 결과다.

기술문서팀은 스펙을 통해서 매뉴얼과 도움말을 작성할 수 있다.


소프트웨어 스펙이 완성된 후에는 많은 일들이 벌어진다. 기술문서팀은 소프트웨어를 동작시켜 보지도 않고 매뉴얼을 미리 작성한다. 단지 화면 캡쳐만 소프트웨어 개발 후 추가할 뿐이다. 이뿐만 아니다. 고객지원 부서는 고객 지원에 필요한 준비를 해 놓고 교육팀은 교육 준비를 한다. 이처럼 소프트웨어 스펙을 보고 많은 사람들이 자신의 일을 수행해야 하는데 바쁘다고 스펙 없이 개발을 하는 것은 개발자 중심의 사고방식이며 프로젝트가 효율적으로 진행되지도 않는다.

외주 업체는 스펙을 통해서 외주 업무를 정확하게 파악하고 SRS를 기준으로 계약을 할 수 있다.


우리나라에서는 많은 소프트웨어 프로젝트가 스펙도 없이 진행이 된다. 대략의 요구사항을 기반으로 계약하고 진행되는 프로젝트는 정상적으로 진행되기 어렵다. 고객이 수시로 요구사항을 무리하게 바꿔도 하소연하기 어렵다. 또한, 분석을 제대로 하지 않고 진행을 하므로 요구사항만으로는 프로젝트의 규모를 제대로 산정하기 어렵다. 그래서 계약 시는 성공적인 계약으로 생각되지만 프로젝트를 진행할수록 손해를 보는 경우도 허다하다. 우리나라도 스펙을 기준으로 계약을 하는 관행이 자리잡아야 한다.

2020년 1월 5일 일요일

[Software Spec Series 3] 스펙에 대한 오해의 증거


소프트웨어 프로젝트에서 스펙 작성의 중요성에 대해 얘기를 해보면 공감을 하는 사람도 있는가 하면 부정적인 의견을 가지고 있는 사람도 많다. 대부분은 스펙에 대한 오해에서 비롯된 것이다. 이 오해를 해소하는 것은 매우 중요하다. 오해가 풀려야 스펙 작성의 주요성을 공감할 수 있고 스펙 작성을 위해 노력할 것이다. 스펙 작성에 대한 어떠한 오해들이 있는지 알아보자.


스펙을 적는 것이 좋은 줄 몰라서 안 적는 게 아니다.


스펙을 제대로 적고 소프트웨어를 개발하는 것이 좋은 줄은 아는데 어떤 사정 때문에 스펙을 제대로 적고 있지 않다는 얘기다. 필요하면 언제든지 제대로 적을 수 있다고 주장하기도 한다. 일단, 이렇게 주장을 하는 경우는 스펙 작성이 소프트웨어 프로젝트에서 얼마나 중요하고 필요한지 잘 모를 가능성이 매우 높다. 스펙은 누가 시켜서, 의무라서 작성하는 것이 아니라 소프트웨어 프로젝트를 성공시키는 중요한 요소이기 때문에 작성하는 것이다. 그래서 이를 제대로 깨닫고 있는 경우라면 스펙을 작성하지 않을 리가 없다. 단, 프로젝트의 성격에 따라서 스펙의 양과 작성법은 달라질 수 있다. 스펙을 작성하고 있지 않다면 스펙을 제대로 작성하는 것이 프로젝트를 성공하는데 얼마나 중요한지 모르는 것이다.

소프트웨어를 만들어 보기 전에는 천재도 내용을 다 알 수 없다.


맞는 말이기도 하다. 우리는 100% 모든 것을 아는 것만 프로젝트로 수행하지는 않는다. 성공을 장담할 수 없는 알고리즘을 개발하기도 하고, 한번도 사용해보지 않는 상용 라이브러리를 사용해서 소프트웨어를 개발하기도 한다. 또한, 프로젝트 중후반까지 고객의 요구사항을 다 파악하지 못하기도 하고, 고객 요구사항이 계속 바뀌기도 한다. 그 외에도 소프트웨어 프로젝트는 어려움투성이다. 그래서 일단 개발해 봐야 한다는 주장도 있지만 필자는 반대로 그러기 때문에 스펙을 제대로 작성해야 한다고 주장한다. 스펙에는 이런 어려움과 미지수까지 사실 그대로 적시를 해야 하며, 스펙을 작성하는 도중에 검증을 통해서 불확실성을 줄여 나가야 한다. 이런 어려운 프로젝트를 수행하면서도 프로젝트 성공 가능성을 높이는 가장 좋은 방법은 스펙을 적절하게 작성하는 것이다. 

나도 작성할 줄 아는 데 적을 시간이 없다.


시간이 없어서 스펙을 작성하지 못한다는 것은 모순과 같다. 스펙을 제대로 작성하는 이유는 최단 시간에 소프트웨어를 개발하는데 필요하기 때문이다. 스펙이라고 얘기를 하면 방대한 문서가 먼저 떠오르지만, 스펙은 상황에 따라서 가장 적절하게 작성해야 하고 의외로 적게 잘 작성한 스펙도 많다. 프로젝트의 일정이 절대적으로 짧아서 스펙을 작성할 시간이 없어서 그냥 프로젝트를 진행한다면, 대부분의 경우 스펙을 제대로 작성하는 것보다 프로젝트는 더 오래 걸린다. 모든 프로젝트는 적절한 인력과 시간이 필요하지만 비즈니스 상황상 시간이 절대적으로 부족하다면 스펙을 작성하지 않는 것보다 스펙을 효율적으로 신속하게 작성하고 프로젝트를 진행하는 것이 낫다. 스펙을 항상 일정한 절차를 거쳐서 상세하게 작성해야 한다는 것은 오해에 불과하다. 프로젝트의 여건에 맞게 프로젝트를 가장 빨리 끝낼 수 있는 방법으로 작성하는 것이 스펙을 제대로 작성하는 방법이다.

나도 작성해 보았는데 우리 경우는 달라서 적기가 어렵다.


많은 회사에서 자신들은 일반적인 소프트웨어가 아니라서 스펙을 작성할 수 없다고 한다. 이유는 매우 다양하다. 게임이라서, 펌웨어라서, 라이브러리라서, 매주 업데이트를 해야 해서, 회사 내부용이라서 다르다고 한다. 우리는 달라서 스펙을 작성할 필요가 없다고 주장하는 것은 스펙을 제대로 작성하지 못하는 것에 대한 핑계와 오해일 뿐이다. 스펙 관점으로 보면 모든 소프트웨어는 같다. 모든 소프트웨어는 스펙이 존재하며 스펙을 적절히 작성하는 것은 소프트웨어 프로젝트를 성공하는데 중요한 요소다. 스펙을 적절히 작성한다는 의미에 대해서 이 시리즈에서 얘기를 할 것이다.


기획 부서에서 주는 문서가 충실치 않아서 스펙을 적을 수가 없다.


기획 부서에서 제대로 기획서를 작성해서 전달하면 소프트웨어 스펙을 작성하는데 많은 도움이 된다. 하지만 기획 부서에서 고객 요구사항을 제대로 파악하지 못하거나, 소프트웨어 비전과 전략을 제대로 정리해서 전달하지 못하는 경우는 매우 흔하다. 심지어는 기획을 거치지 않고 요구사항 몇 줄을 가지고 개발팀으로 넘어와서 스펙을 작성해야 하는 경우도 있다. 그렇다고 기획팀을 핑계로 스펙 작성에 소홀하면 그 피해는 고스란히 개발팀에게 떨어지고, 프로젝트는 실패를 향해 달려갈 수 있다. 기획이 부실하다면 소프트웨어 분석을 담당한 분석 아키텍트가 기획이 해야 할 역할도 일부 수행하는 것이 좋다. 소프트웨어의 비전과 전략을 파악하고 고객 요구사항을 좀더 파악해야 한다. 그리고 스펙에서 전략에 해당하는 부분은 기획 부서의 확인을 받아야 한다. 기획 부서의 핑계를 대 봤자 모든 문제는 개발팀에게 부담으로 되돌아 온다.

폭포수 모델과 달리 우리는 Agile이라서 잘 적을 필요 없다.


스펙을 제대로 작성하는 것은 폭포수 모델에서나 하는 것이라는 오해다. 스펙 작성이 어렵다는 것은 익히 알려져서 Agile을 선택하는 회사도 있다. Agile을 적용하면 스펙을 어렵게 작성하지 않아도 된다는 오해에서 비롯된 것이다. 현실에서 폭포수 모델을 사용하는 소프트웨어 회사는 거의 없다. 방법론과는 상관없이 소프트웨어 스펙은 중요하다. Agile이라고 하더라도 스펙의 내용이 바뀌지는 않는다. 적는 방법만 달라질 뿐이다. 폭포수 모델에서 소프트웨어 스펙을 잘 작성할 수 있는 역량을 가지고 있다면 Agile을 적용한 프로젝트에서도 효율적으로 스펙을 작성할 수 있다. Agile을 적용한 프로젝트에서도 스펙은 잘 작성해야 한다.

잘 적은 샘플 보여주세요.


우리는 프로그래밍을 배울 때 좋은 샘플을 많이 보면서 배웠다. 이 방법은 매우 유용했다. 그래서 스펙 작성을 배울 때도 샘플을 보여 달라고 한다. 그리고 샘플에 적힌 내용을 자신의 프로젝트에 맞게 바꾸곤 한다. 이렇게 스펙을 작성하고 작성법을 배운다면 100% 실패한다. 세상의 모든 프로젝트는 서로 다른데 샘플을 보고 작성한다는 것은 어불성설이다. 샘플 보면서는 각 항목의 숨겨진 뜻과 생략된 내용, 적는 과정을 알 수 없다. 10년에 걸쳐서 피아노를 연습한 피아니스트의 현재 연주 동영상을 보고 그대로 따라하는 것과 다를 바가 없다. 많은 경우 샘플을 도움이 되기 보다는 독이 된다. 샘플에 적혀 있는 내용은 그 상황에서만 맞는 내용인데 샘플을 보고 따라서 적다가는 잘못된 방법이 반복되고 고착화 될 수 있다. 샘플에 잘못된 방법으로 적힌 내용이 있는 경우에는 더욱 문제가 된다. 잘못된 것인데도 불구하고 이렇게 적는 것이 올바른 방법인줄로 착각하고 샘플을 참고하여 계속 잘못된 방법으로 적게 된다. 샘플을 보고 작성하는 것보다 혼자서 많은 생각을 하면서 직접 맨땅에 작성해보는 것이 더 나을 때가 많다. 그럼에도 불구하고 대부분의 사람들은 샘플에 대한 유혹을 꺾을 수가 없다. 

실리콘밸리에서는 한번 적으면 스펙이 변경되지 않는다는 겁니까?


현실 프로젝트에서 프로젝트 도중에 스펙이 변경되지 않는 경우는 거의 없다. 스펙이 변경되기 때문에 스펙을 작성하지 못하는 것이 아니고 스펙 변경이 기정 사실이고 그럼에도 불구하고 스펙을 제대로 작성해야 한다. 변경이 잦은 프로젝트는 프로젝트 이해관계자들이 서로 다른 스펙을 참조하는 실수도 발생한다. 두 개발자가 서로 다른 스펙을 보고 개발을 한다면 소프트웨어는 통합이 안되거나 버그를 만들어 낼 것이다. 또한 영업에서 구버전의 스펙을 참조하면 엉뚱한 영업을 할 수도 있다. 그래서 스펙의 변경 관리는 매우 중요하다. 변경이 잦은 프로젝트에서는 스펙을 작성하는 방법도 바뀔 수 있다. 변경을 쉽게 받아들이기 위한 노하우를 적용해야 한다. 모든 프로젝트는 다르며 작성법도 프로젝트 성격에 맞게 적용해야 한다.

2019년 12월 26일 목요일

[Software Spec Series 2] 소프트웨어 프로젝트 실패의 원인

우리 주변에서 실패한 소프트웨어 프로젝트를 보는 것은 어려운 일이 아니다. 프로젝트를 성공하는 방법을 배우기 위해서는 프로젝트를 제대로 진행하는 방법을 연구하는 것도 필요하지만 프로젝트가 왜 실패하는지 살펴보는 것도 도움이 될 것이다. 프로젝트 실패에 대한 기준은 제각각이다. 그래서 어떤 경우에 프로젝트가 실패했다고 할 수 있는지 알아보자.
  • 약속된 일정 내에 제품 또는 서비스를 출시하지 못했다.
  • 소프트웨어가 요구되는 품질을 충족하지 못했다. (기능 요구사항, 성능, 안정성, 사용성, 확장성 등)
  • 프로젝트에 꼭 필요한 기술 개발에 실패했다. 
  • 아키텍처가 엉망진창이 되어서 유지보수가 어렵게 됐다.
  • 프로젝트에 계획된 예산보다 많은 비용을 지출했다.
  • 프로젝트 내내 야근을 거듭하여 조직의 사기가 떨어지고 퇴사자가 많이 발생했다.
          직접적인 실패와 억지로 일정을 맞추려다 보니 다른 문제를 야기하는 간접적인 실패까지 예로 들어봤다. 이런 저런 이유로 실패하는 프로젝트는 매우 많다. 또한 실패하는 이유도 매우 다양한다. 필자는 이 중에서 가장 중요하다고 생각하는 하나에 대해서 얘기를 하려고 한다. 우선은 프로젝트를 왜 실패하는지 다양한 원인을 알아보자.


          • 고객의 요구사항을 충분히 파악하지 못했다.
          • 제품의 방향을 빨리 정하지 못하고 우왕좌왕하면서 프로젝트 앞부분에서 상당히 많은 시간을 소모하여 정작 개발 기간이 부족하게 되었다.
          • 스펙과 설계를 제대로 작성하지 않고 코딩을 시작해서 엉뚱한 방향으로 개발을 하였다.
          • 작성된 스펙을 프로젝트 이해관계자들이 충분히 리뷰 하지 않아 잘못된 스펙으로 개발하였다.
          • 프로젝트를 진행할수록 새로운 요구사항이 계속 발견되어서 프로젝트가 한없이 늘어졌다.
          • 변경된 요구사항을 제대로 관리하지 않아서 프로젝트 팀원들이 서로 다른 기준으로 개발을 하였다.
          • 상명하복식으로 지정된 출시 일정을 맞추기 위해서 급하게 코딩부터 시작했다. 나중에 잘못된 코드를 고치느라고 시간이 더 소요되었다.
          • 충분히 훈련되지 않은 개발자들을 투입하여 초반에 우왕좌왕하느라고 시간을 많이 지체했다.
          • 일정관리를 대충해서 프로젝트가 지연되고 있다는 징후를 눈치채지 못했다.
          • 리스크 관리를 하지 않아서 리스크로 인해서 프로젝트를 실패했다.
          • 프로젝트 막판에 경영진이나 주요 고객이 프로젝트 방향을 완전히 틀어서 거의 처음부터 다시 개발해야 했다.
          • 프로젝트 팀원들의 팀워크에 문제가 있어서 지속적으로 불화가 발생하여 프로젝트가 산으로 갔다.
          • 도입한 외부 필수 기술이 기대처럼 동작하지 않았다. 이것을 프로젝트 막바지에 알게 되었다.
          • 테스트 팀에 제대로 된 스펙을 전달하지 못해서 테스트 준비를 제대로 하지 못했다.
          • 회사의 표준 프로세스를 강요하여 문서를 너무 많이 만들다 보니 정작 개발에는 소홀해졌다.


          이외에도 실패 원인은 끝도 없이 많을 것이다. 이를 분류해보면 스펙, 프로젝트팀, 프로젝트 관리, 고객, 기술 등 다양하다. 필자는 이중에서 가장 중요하게 생각하는 요인은 “스펙”이다. 가장 많은 원인이 스펙과 관련이 있다. 또한 소프트웨어 버그의 절반 이상은 스펙으로부터 발생한다고 알려져 있다.

          프로젝트가 아주 작다면 스펙을 제대로 적지 않고 요구사항 몇 줄로 개발해 나가도 소프트웨어를 무사히 완성하기도 한다. 소수의 경험 많은 개발자가 개발을 주도하는 경우 요구사항을 대충 알려줘도 찰떡 같이 알아듣고 개발을 잘하기도 한다. 하지만, 수백명이 투입되는 대규모 프로젝트에서는 매우 잘 정리된 스펙 문서가 필요한 경우가 일반적이다. 외국에 외주를 줄 경우 자세히 적힌 스펙 문서와 인수 테스트 계획이 필요하다.

          소규모 프로젝트에서의 성공 경험을 대규모 프로젝트에 적용해서 실패를 하기도 하고, 반대로 대규모 프로젝트의 방법론이 중소규모 프로젝트에서 실패의 원인이 되기도 한다.

          요구사항이 누락되거나 충분히 분석이 안된 스펙도 문제지만 너무 자세히 적거나 많은 문서를 적는 것도 문제가 된다. 대규모 방법론을 따르는 회사에서는 이런 함정에 종종 빠진다. 개발은 문서대로 진행되지 않을 뿐만 아니라 문서가 너무 많아서 수시로 바뀌는 요구사항을 문서에 제대로 반영하지 못한다.

          따라서 엄격한 프로세스로 규제를 하는 것도 어렵다. 자율에 맡겨도 쉽지 않다. 필자가 생각하는 가장 좋은 방법은 원칙만 지킬 수 있는 최소한의 프로세스가 있는 환경에서 좋은 문화를 가지는 것이다. 빨리빨리 문화를 지양하고 적절히 분석하고 설계를 한 후 프로젝트를 진행하는 것이 더 빠르다는 인식을 공유해야 한다. 실제로 가장 빠른 방법이다. 모든 이해관계자들이 스펙을 철저히 리뷰하고 쉽게 요구사항을 바꾸지 않아야 한다. 이런 문화와 관행을 만들어가는 것이 프로세스보다 더 중요하다. 그래야 회사에 역량이 축적된다. 그렇게 좋은 문화와 축적된 역량이 충분해야 어떠한 프로젝트라도 성공으로 이끌 수 있다.

          좋은 환경이 있어도 스펙을 제대로 적을 수 있는 역량이 부족하다면 소프트웨어 프로젝트 성공은 어렵다. 스펙을 제대로 적는 역량은 소프트웨어를 개발하는데 있어서 가장 어려운 역량이며 소질이 있는 개발자도 제대로 하려면 10년 이상의 경험과 노력이 필요하다. 꾸준히 투자하는 방법 외에 기가 막힌 방법은 없다.