효과적인 연습의 부족은 예측 불가능하고 반복되는 에러, 낭비된 노력으로 이어진다. 이는 결국 고객들이 늘어나는 예산, 맞추지 못하는 D-Day 때문에 실망하게 되는 결과를 초래한다.
이러한 경험은 우리의 행동을 제한할 것이고, 결국에는 수많은 제한사항들에 짓눌려 일을 완수하지 못하는 자신을 발견하게 될 것이다. 이러한 번거럽고 어려운 process는 오히려 예방하려고 했던 문제를 야기할 수 있다.
2001년 초, 많은 기업의 소프트웨어 팀이 비대한 process에 의해 고통받는 사실을 확인한 후, 자신들을 agile alliance라고 부른 전문가들은 신속하게 작업하고 변화에 대응할 수 있는 가치와 원칙을 설명하였는데, 이것이 바로 The Manifesto of the Agile Alliance(Aglile Alliance의 선언문)이다.
Extreme Programming은 가장 유명한 에자일 방법론이다. 이는 간단하면서도 상호의존적인 일련의 관행으로 구성된다.
고객과 개발자가 서로 협력하여 서로의 문제를 인식하고 해당 문제를 해결하기 위해서 함께 작업하기를 바란다. Extreme Programming에서 고객이란 기능을 정의하고 우선순위를 지정하는 개인이나 그룹이다. 고객에 대한 더 많은 해석이 있지만, Extreme Programming에서 고객은 팀의 일부이다.
프로젝트를 계획하려면 요구사항에 대해서 알아야하지만, 많은 것을 알 필요는없다. 계획을 세우는데 요구사항을 추정할 만큼만 알면 된다. Extreme Programming에서 user story는 요구사항에 대한 지속적인 대화를 나타내는 기억술적 토큰이다. 이는 고객이 우선순위와 예상비용에 따라 요구사항의 구현일정을 정하는데 사용되는 계획도구이다.
Extreme Programming프로젝트는 2주마다 작동하는 소프트웨어를 제공한다. 이러한 2주간의 반복과정을 통해 이해관계자의 요구사항중 일부를 충족하는 작동하는 소프트웨어가 탄생한다. 각 반복과정의 끝에, 시스템은 피드백을 위해서 이해당사자들에게 시연된다.
유저 이야기에 대한 수용 테스트는 반복적으로 실행할 수 있는 일종의 스크립팅 언어로 작성된다. 고객이 지정한대로 시스템이 작동하는지 확인하는 역할을 한다. 승인 테스트에 통과하면 통과된 테스트 본문에 추가된다.
모든 코드는 동일한 워크스테이션에서 함께 작업하는 프로그래머 쌍에 의해 작성된다. 한명은 키보드를 통해서 타이핑하고 다른 한명을 그 모습을 보면서 오류나 개선점을 찾는다. 이러한 한 쌍 구성원은 반복적으로 바뀌며, 이러한 과정을 통해서 팀 전체에 지식이 확산된다. 또한 팀 전체에 전문성이 확산되어 긴급 상황에는 다른 팀원이 전문가를 대체할 수 있다.
우선, 실패할만한 테스트 케이스를 생성한다. 그리고 이 테스트 케이스를 통과할 수 있는 코드를 작성한다. 테스트 케이스와 코드는 함께 진화하지만, 테스트 케이스가 코드보다 아주 작은 비율로 앞서게 된다. 이러한 결과로 프로그래머는 프로그램이 작동하는지 확인할 수 있다.
코드와 테스트케이스를 따로 작성하기 때문에, 결함도가 낮아지는 경향을 보인다.
어떠한 프로그래머도 특정 모듈이나 기술에 대해 개별적으로 책임을 지지 않는다. 누구도 다른 사람보다 모듈이나 기술에 대해 더 많은 권한을 가질 수 없다.
프로그래머가 모듈을 수정한 후 다시 체크인할 때는 자신보다 먼저 모듈을 체크인한 사람이 변경한 내용과 병합할 준비가 되어있어야 한다. 이러한 과정이 길어지는 것을 막기 위해서 팀 구성원들은 그들의 모듈을 자주 살펴봐야한다.
소프트웨어 프로젝트는 단거리 달리기가 아닌 마라톤이다. 빠르게 끝내기 위해서 팀은 지속가능한 속도로 에너지를 유지하면서 진행해야한다.
이러한 개방된 환경이 오히려 생산성이 더 좋다.
고객이 기능의 중요성을 결정하고 개발자는 해당기능을 구현하는데 비용이 얼마나 드는지 결정한다. 각 릴리스와 반복이 시작될 때 개발자는 마지막 반복 또는 릴리스에서 완료할 수 있었던 양을 기준으로 고객에게 예산을 제공한다.
Extreme Programming 팀은 디자인을 최대한 단순하면서도 표현력이 풍부하도록 만든다. 현재 시스템이 구현하고 있는 스토리에 가장 적합한 디자인이 되도록 시스템의 디자인을 반복을 통해 수정한다.
기능을 계속 추가하고 버그를 처리할 수록 코드의 구조는 저하된다. 방치되면 이러한 저하가 엉켜서 유지관리가 불가능해진다.
Extreme Programming은 반복적인 리팩토링을 통해 이러한 저하를 개선한다. 이는 시스템의 동작에 영향을 미치지 않고 시스템의 구조를 개선하는 것이다.
전체 시스템을 하나로 묶는 큰 그림이다.
프로젝트를 시작할 때, 개발자와 고객들은 정말 주요한 고객들의 이야기(요구사항 등)를 수집하지만, 모든 이야기를 수집하지는 않는다. 프로젝트가 진행되면서 고객들의 이야기는 점점 더 많아질 것이기 때문이다. 너무 작은 이야기들은 다른 작은 이야기들과 합쳐져야 하고, 너무 규모가 큰 이야기는 적절한 크기의 작은 이야기들로 분할되어야 한다.
이야기의 실제 크기를 알기 위해서 velocity라는 요소가 필요하다. 정확한 velocity가 있다면 스토리당 추정치를 velocity로 곱하여 스트리의 실제 추정치를 구할 수 있다. 하지만, 개발 팀은 초기에 velocity가 어느정도 되는지 모르기 때문에 이를 알기 위해서 프로로타입을 만드는 기간을 가질 수 있는데 이러한 기간을 spike라고 한다.
이렇게 측정된 velocity값에 따라서 개발자와 고객을 릴리스 일정을 결정한다. 고객은 자신들이 구현되기를 원하는 이야기를 선택하지만, 현재 velocity보다 큰 것을 고를 수 없다. 하지만, 프로젝트가 진행됨에 있어서 velocity값은 더욱 정확해 질것이고, velocity값이 변함에 따라서 일정도 같이 변화할 수 있다.
그 다음 반복작업의 크기를 결정한다. 반복이 시작된 이후에는 고객들이 그들의 이야기(요구사항)을 변경할 수 없다. 이러한 스토리가 모두 완료되지 않더라도 반복은 지정된 날짜에 종료된다. 완료된 이야기에 대한 추정치가 합산되고, 이는 다음 반복을 계획하는데 사용된다.
개발자들은 스토리를 개발 작업으로 나눈다. 이렇게 작업들이 분할되면, 개발자들은 한명씩 구현하려는 작업에 등록한다. 꼭 자신의 전문분야에 등록할 필요는 없으며, 이렇게 진행하면 팀 전체적으로 프로젝트에 대한 이해도가 높아진다.
2주마다 현재의 반복이 끝나고 다음 반복이 시작된다. 각 반복이 끝날 때 마다 실행파일이 고객에게 시연된다. 그리고 고객들은 이것에 대한 피드백을 제공한다.
모든 기능에 대해 작동을 검증하는 테스트가 있다는 장점이 있다. 또한. 테스트를 먼저 하는 행위는 소프트웨어를 편리하게 호출할 수 있도록 설계한다. 게다가 테스트를 먼저 작성함으로써, 테스트 가능한 프로그램을 설계하게 된다.
이렇게 호출가능하고 테스트가 가능하려면 소프트웨어가 주변환경으로부터 분리되어야 한다. 따라서 테스트를 작성하는 첫번째 단계는 소프트웨어를 분리하는 것이다.
단위 테스트는 필요하지만, 검증 도구로는 충분하지 않다. 이는 시스템의 작은 요소가 예상대로 작동하는지 확인하지만 시스템 전체적으로 재대로 작동하는지 확인하지는 않는다. 단위 테스트가 시스템의 개별 메커니즘을 확인하는 화이트 박스 테스트라면, 수용 테스트는 고객 요구 사항이 충족되는지 확인하는 블랙 박스 테스트이다.
이는 시스템의 내부에 대해서 잘 모르는 사람들에 의해 작성된다.
프로그램은 읽기 쉬워야 하고 변경하기도 쉬워야 하고, 주요한 기능들은 분리되어 변경이 쉽도록 구성되어야 한다.
리팩토링의 목표는 매일 코드를 정리하는 것이다. 우리가 원하는 것은 최소한의 노력으로 시스템을 확장하고 수정하는 것이다. 이를 위해서 코드의 깔끔함은 필수이다. 아무리 많은 디자인 패턴과 규칙들이 적용되었더라도, 코드가 더러워서 읽기가 힘들다면 아무런 소용이 없다.