2004-10-04

반복적(Iterative) 개발

무엇을 반복하는가?

광의로 반복적 개발이란 무엇인가를 반복하면서 시스템을 개발하는 걸 의미한다. 이렇게 넓은 의미에서 본다면 단순히 코딩/단위 테스트가 반복되는 개발도 반복적이다. 그래서 반복적 개발이 가치를 지니려면 반복의 대상이 되는 활동의 폭 혹은 수에 대한 협의의 의미 부여가 필요하다.

논의의 단순화를 위해 시스템 개발이 요구수항 수집, 요구사항 분석, 설계, 구현(단위 테스트를 포함한), 테스트, 배치 등의 활동으로 구성된다고 가정하자.

앞 에서 예로 든 반복은 구현이라는 단위 활동 내에서 이루어질 뿐이다. 반복적 개발이 가치가 있으려면 하나의 활동 내에서가 아닌 여려 활동들이 결합하여 반복되어야 한다. 이 때 활동들의 결합은 근접한 것(설계와 구현, 요구사항 수집과 요구사항 분석 등) 사이에서 이루어지는 것이 통상적이다.

따라서 반복적 개발이란 요구사항 수집, 요구사항 분석, 설계, 구현, 테스트, 배치 등의 활동이 둘 이상으로 결합되어 2회 이상 반복되는 형태를 지칭한다.


왜 반복하는가?

성공적인 시스템 구축을 위해서 반복한다. 자세한 설명은 Iterative Development(http://www.objectmentor.com/writeUps/IterativeDevelopment)를 참조한다.


반복의 강도

앞 에서의 정의를 빌려서 우리는 어떤 프로젝트가 반복적인 개발을 수행하고 있는지 아닌지를 판단할 수 있다. 그 다음으로는 반복의 강도를 계산해야 한다. 간단하게 반복의 강도는 결합되어 반복되는 개발 활동들의 수와 반복의 빈도를 통해서 파악한다.

반복의 강도 = 결합된 활동 수 X 반복의 빈도

[TODO] 반복의 강도와 프로세스 효율성의 상관 관계


반복하여 무엇을 개발하는가?

우리가 개발하는 시스템이 A, B, C 등의 서브시스템으로 분리되어 있다고 가정하자. 그리고 각각의 서브시스템(A)은 여러 기능(A1, A2, A3) 등으로 다시 분리된다고 보자.

이런 조건에서 무엇을 반복하여 개발하는가에 대한 질문에는 두개의 답이 있을 수 있다. 일단 반복 주기가 X, Y, Z 등의 3 주기로 구성된다고 가정하자.

첫번째는 (X-A), (Y-B), (Z-C) 등의 방식으로 개발하는 것이고, 두번째는 (X-A1, B1, C1), (Y-A2, B2, C2), (Z-A3, B3, C3) 등의 방식으로 개발하는 것이다.

모 든 서브시스템이 중요성, 복잡성 측면에서 동일하다면 어느 방식이든 문제가 없다. 단 이런 상황은 예외일 것이다. 따라서 중요하고 복잡한 서브시스템에 집중할 수 있어야 한다. 그리고 경우에 따라서는 프로젝트 중간에 특정 서브시스템을 개발 범위에서 함몰 비용을 최소화하면서 제외(포기)할 수도 있어야 한다. 결국 학습 효과를 충분히 발휘하는데에도 적합한 첫번째 방식이 바람직하다.

따라서 첫번째 개발 주기(X)에서 A, B, C 중 중요한 서브시스템을 먼저 개발한다. 중요한 것은 서브시스템이 사용자에게 제공하는 가치와 그것의 구현 위험도를 고려하여 결정하면 된다.

여기서 각 서브시스템의 중요도가 A, B, C 순이라고 가정하자. 그런데 기능 수준에서는 B의 기능 중 하나(B1)가 A의 기능 중 하나(A1)보다 중요도가 높다면 어떻게 무엇을 개발할 것인가?

이 때는 첫번째와 두번째 방식을 혼용해서 A2, A3, B1의 기능을 첫번째 반복 주기(X)에서 개발할 수도 있을 것이다.

[TODO] 첫번째 방식을 사용하여 효과를 극대화하려면 정교하게 고안된 인력 운영 기법을 갖추고 있어야 한다.


개발 속도(Velocity)

프로젝트 팀이나 개별 팀원의 개발 속도는 프로젝트 관리에 중요한 정보이다. 초기에는 개략적으로 개발 속도를 예측하고 반복을 진행하면서 그 속도를 실제적인 것으로 구체화해야 한다. 개발 속도의 단위는 반복 주기 단위로 한다.

개발 속도 = 하나의 반복 주기에 완료한 기능의 포인트

기능의 규모와 복잡성을 객관화하는 수단이 있어야 한다. 일단은 이를 추상화하여 기능의 단위라고 지칭한다. 실질적으로는 Function Point 등을 이용할 수 있을 것이다.


반복적 개발에 따른 이슈

(1) 고객의 참여

반복적 개발에는 (특히 요구사항 분석 활동이 반복에 포함된다면) 고객의 참여가 중요하다. 고객이 반복의 시작과 종료 시에 병목점이 될 여지가 높기 때문에 이를 고객의 적극적 참여를 통해서 해결해야 한다.

[TODO] 이번 반복에서 3개의 기능(A1, A2, A3)을 개발해야 한다. 그리고 이들 기능은 독립적인 서브팀(X, Y, Z)에 할당되었다. 각각의 기능에 대해서 요구사항을 내고 만들어진 기능에 대한 검증을 하는 고객이 독립적으로 존재한다면 갈등의 소지는 없다. 그런데 1명의 고객이 3개의 기능에 대해서 모두 총괄한다면 어떻게 할 것인가? 개발 팀의 대기 시간이 길어지는 명목 현상을 어떻게 해소할 것인가? 이전 반복에서 발생한 문제의 해결이나 미진한 기능의 추가 개발과 요구사항 분석 단계를 병행해서 대기 시간을 줄일 수 있을까? 혹은 각 서브팀별로 반복의 시작과 종료를 달리해서 대기 시간을 줄일 수 있을까?


(2) 짧은 반복 주기

반복에 요구사항 분석, 설계, 구현, 테스트 등의 활동이 포함된다고 가정한다. 반복주기는 최소 1주에서 최대 8주 이내에서 선택한다. 그리고 각 반복의 기간은 동일해야 한다. 그래야지만 평가 혹은 비교 기준으로 삼을 수 있다.

6 개월 이내의 프로젝트는 2 주 단위로 반복을 가져간다. 첫번째 1 개월과 마지막 1 개월은 요구사항 수집과 배치(인수 테스트 포함) 활동을 위해 사용한다고 하면 최대 8 차례의 반복이 가능하다.

12 개월 이내의 프로젝트는 4 주 단위로 반복을 가져간다. 첫번째 2 개월과 마지막 2 개월은 요구사항 수집과 배치(인수 테스트 포함) 활동을 위해 사용한다고 하면 역시 최대 8 차례의 반복의 가능하다.

대 략 XP(eXtreme Programming)는 1주 혹은 2주, Scrum은 4주(30일), RUP는 8주 이상의 반복 주기를 갖는다. 물론 Scrum을 제외하고 XP 혹은 RUP가 이를 공식화한 것은 아니다. 한 프로젝트에서 3 차례 이상의 반복이 가능하다면 반복 주기의 크기는 부차적이다. 반복 주기는 (고객에게) 의미 있는 가치를 제공하는 개발 팀의 속도를 고려해서 결정하면 충분할 것이다.


(3) Time-Box 준수

계획된 혹은 합의된 반복의 시작일과 종료일은 항상 준수한다.

정 해진 반복 주기 내에서 완료하기로 한 기능을 개발하지 못하는 상황이 왔을 때 개발 주기의 완료일을 연장하면 전체 반복 주기의 흐름이 깨진다. 개발 대상을 축소하더라도 개발 주기를 지키는 것이 현명하다. 기간의 연장은 이번 반복에서 (우리가) 실패했다는 사실을 은폐하는 도구로 사용될 가능성이 높으며, 이는 반성할 기회의 상실을 의미할 수 있다. 프로젝트 팀의 도덕성 유지를 위해서 Time-Box는 항상 준수한다.

[TODO] 앞의 서술에서 반복 주기를 서브시스템과 기능을 가지고 결정하는 듯한 입장을 명확하게 할 필요가 있다. 엄밀하게는 서브시스템과 기능을 가지고 Time-Box를 설계하는 것이 아니라 그 합의된 Time-Box에 서브시스템과 기능을 끼어 넣어야 한다. 닭이 먼저냐 달걀이 먼저냐의 문제로 비추어지기도 하겠지만 이는 반복적 개발에 대한 근본적인 문제이다.


(4) 반성과 학습

반복은 Time-Box 시간의 경과로 종료되지 않는다. 몇가지 질문들에 대한 대답과 다음 반복을 위한 준비 혹은 사색이 반복의 종료의 절대 기준이다.

이 번 반복에서 우리는 무엇을 했는가? 반복의 시작에 설정한 목표들을 총족시켰는가? 충족하지 못했다면 그 이유는? 그 이유에 대한 해결 방안은 있는가? 충족했다면 그 이유는? 일하는 방식은 적절했는가? 더 나은 방식이 있는가? 버려야(포기해야) 하는 것과 강화해야 하는 것은?

반복의 종료는 이렇게 간단한 다과와 함께 전체 프로젝트 팀원들이 참여한 미팅으로 종료되어야 한다.

[TODO] Scrum은 매일 아침 30분 이내의 회의를 갖는다. 이런 형태의 회의를 갖는 것이 바람직한가? 개발 주기가 짧다면 아침의 회의가 요식 행위가 되거나 반복 종료 미팅과 중복되지 않을까? 일일보고는?

[TODO] 대부분의 프로젝트에는 주간회의와 월간회의가 존재하는데 만일 반복 개발을 한다면 이를 Time-Box와 동기화 시켜야 한다.


(5) 기능 간의 의존성 관리

중 요한 기능을 먼저 개발한다라는 기준의 준수를 어렵게 하는 것이 기능 간의 의존성이다. 가령 중요도가 가장 높은 A1 기능은 중요도가 낮은 B1 기능에 의존하고 있다. 이런 상황에서 A1 보다는 B1을 먼저 개발해야 하는가? 이렇게 하면 가장 중요한 기능의 개발이 가장 뒤로 밀릴 것이다. 이를 극복하기 위해서 우리는 Mock 기법을 사용한다. 즉 B1 기능을 거짓으로 구현하는 것이다. 이 때는 B1 기능들의 인터페이스도 최소한으로 설계한다.


(6) 재사용

프로젝트가 시작한 후 얼마나 빠른 시간 내에 반복에 들어 갈 수 있는가? 이에 대한 대답이 프로젝트 팀의 역량에 대한 단적인 표상이 된다. 모든 것을 백지에서 시작한다면 반복에 들어가는 시간이 뒤로 밀려질 것이며 이는 최종적으로 반복 개발 자체를 불가능하게 한다.

반복은 프로젝트 팀이 일정 수준 이상의 역량을 확보하고 있을 때 가능하다. 반복적 개발이 역량이 낮은 팀의 생산성(시스템의 품질을 포함한)을 어느 수준 이상으로 높여 주지는 않는다.

예를 들어, 참조 아키텍처(Reference Architecture), 프로덕트 라인(Product Line), 애플리케이션 프레임워크, 컴포넌트, 개발 표준 등을 재사용할 수 있을 때 반복적 개발이 가능할 것이다.


참고자료

The Unified Software Development Process
반복적 개발은 프로젝트 위험에 대처하기 위한 것이라는 점을 잘 설명해준다.

Iterative Development
http://www.objectmentor.com/writeUps/IterativeDevelopment
왜 반복적 개발을 해야 하는가에 대한 짧은 대답.

Iterative and Incremental Development: A Brief History
http://www2.umassd.edu/SWPI/xp/articles/r6047.pdf
반복적 개발에 대한 역사를 간략하게 짚어준다.

A spiral model of software development and enhancement
http://www.sce.carleton.ca/faculty/ajila/4106-5006/Spiral%20Model%20Boehm.pdf
고전...

No comments: