이번 주는 소프트웨어 개발 방법론: 애자일 프로세스에 관한 주제를 다루겠다.
이 글을 통해 애자일 프로세스가 무엇인지 정리하고자 한다.
소프트웨어 프로세스
우선, 소프트웨어 프로세스이다. 소프트웨어 프로세스란, 소프트웨어를 개발하기 위해 필요한 활동의 집합을 구조화해서 정리한 집합이다. 즉, 해야할 비슷한 활동들을 묶어놓은 것인데 적게는 4단계, 크게는 5단계로 구분한다.
Specification: 요구사항과 기능을 정의하고 스펙을 명시하는 과정이다.
Design and Implementation: 실제 코드를 설계하고 작성하는 개발과정
Validation: 작성한 코드가 요구사항대로 진행되는지 검증하는 Testing 과정
Evolution: 유지, 보수하는 과정
여기서 Design과 Implementation을 두 단계로 구분해 5가지 과정으로 보기도 한다.
이러한 프로세스의 형태에 따라 프로세스 모델을 구분할 수 있다.
소프트웨어 프로세스 모델: Plan - driven 방식
Plan driven 방식은 말그대로 모든 것을 계획해놓고 계획에 의존해 프로젝트를 개발하는 방식을 의미한다,
- 모든 과정을 사전에 계획해놓고 진행한다.
- Specification 단계에서 요구사항에 대한 문서를 남긴 후 다음 단계를 진행한다.
두 가지 특징이 대표적인데, 이 경우엔 모든 과정을 사전에 계획하기에, 새로운 요구사항이 추가될 경우 이에 대응하기 어렵다는 점, 문서화를 하는 과정에서 필요이상의 오버헤드가 발생한다는 두 가지 단점이 존재한다.
우리는 개발자인데, 코드를 설계하고 작성하는 비중보다 글을 쓰는 비중이 더 높아지는게 비효율적이고 (물론 개발자에게 글 쓰는 능력도 중요하지만), 실제 프로젝트를 해보면 알지만, 추가하고 싶은 기능이 존재할때, 이를 반영해서 다시 계획을 수립하기 어렵다는 단점이 있다.
따라서, 이에 대응하기 위해 등장한 개발 방법론이 애자일 프로세스이다.
소프트웨어 프로세스 모델: Agile Process
Agile이란?
영단어로 민첩한, 날렵한이라는 뜻을 가지고 있다. 무엇에 민첩하고 날렵하다는 것일까? 소프트웨어 개발방법론에서 애자일은 `요구사항 변화에 민첩하다`라는 의미를 가지고 있다. 요구사항 변화에 민첩해 새로운 기능이 추가되면 이를 즉각적으로 반영해 개발하며 배포 시간을 단축하는 프로세스 모델을 애자일 프로세스라고 하는 것이다.
애자일 프로세스에선, Specification 단계 이후에, 문서화를 하는 단계를 없애 문서화 과정에서 오는 오버헤드를 감소시켰다. 문서화 단계를 없앴다고 해서 문서화를 하지 않는 것은 아니다. 문서화의 비중을 줄였다. 정도로 이해하는 것이 좋다.
여기서, 문서화가 중요한 이유를 우선 짚고 넘어가자.
문서화가 중요한 이유
여기 Queue라는 자바 인터페이스를 보자.
Queue가 어떤 역할을 하는지 이 글을 읽는 독자라면, 대부분 다 알고 있을 것이다. 하지만, 자료구조를 배우기 이전에, 내가 Queue를 아직 모른다고 생각하고 해당 코드를 보자. 그러면 여기서 알 수 있는 것은 `Collection` 클래스를 상속받았고 E라는 제네릭을 활용하는 interface라는 것 외에는 알 수 없다.
이 코드를 이해하기 위해선, 작성된 메서드를 하나하나 실행해보며 이해하는 것 외에는 방법이 없다.
하지만, 문서화가 되어있다면?
이렇게 Queue에 대한 설명을 읽으며 해당 코드를 이해할 수 있다. 뭐 Queue는 FIFO, 선입 선출 구조이고.. 이런 느낌으로 이해할 수 있는 것이다.
즉, 문서화를 하게 되면 코드에 대한 이해도를 높일 수 있다. 내 프로젝트를 사용하는 user에게 도움을 주는 것외에도 개발자가 코드를 이해하는데 도움을 주는 역할을 하는 것이다. 실제로 개발자는 알다시피 이직이 잦은 포지션이기에 내가 아닌 다른 사람의 코드를 이해해야할때도, 내가 쓴 코드를 다른 사람이 읽어야할 일도 많기에 문서화는 상당히 중요한 작업이다.
그렇다면, 애자일은 문서화 과정을 축소했다고 하는데, 어떻게 문서화에 대한 비용을 축소하면서 이해도를 유지할 수 있었을까? 애자일 방법론의 하나인 XP (Extreme Programming)에서는 다음과 같은 3가지 방법을 통해 이해도를 높였다.
리팩토링
리팩토링을 통해 2가지 측면에서 코드에 대한 이해도를 높일 수 있다. 첫째는, 리팩토링을 하기 위해선 코드를 그냥 잘 알고 있어야한다. 어떤 흐름으로 작성되어야하는지 알고 있기에 리팩토링 자체가 이해도에 도움이 되고 두번째가 진짜 이유인데, 리팩토링을 하고 나면, 코드를 읽기가 쉽다. 같은 코드라도 지저분한 코드를 지우고, 성능을 높여 코드를 간결하게 하는 과정이기에 코드에 대한 이해도를 높일 수 있는 것이다.
테스트 주도 개발
두번째는 테스트 주도 개발이다. 프로젝트의 테스트 케이스를 작성해 어떠한 input이 들어갔을때 어떠한 output이 나오는지의 과정을 상세하게 확인하는 것이다. Input -> output에 대한 이해를 통해 이해도를 높일 수 있음과 동시에 테스트 코드 자체가 하나의 문서역할을 할 수 있다. 글이 아닌, 코드로 짜여진 문서의 역할을 하는 것이다.
Pair Programming
페어 프로그래밍은 다소, 사소한 개념일 수 있는데 말 그대로 짝을 이루어 개발을 하는 것이다. 한명이 코드를 작성하면 ,다른 한명은 해당 코드를 옆에서 읽는다. 읽으면서 오타를 찾기도하고 코드 리뷰를 하면서 코드에 대한 이해도를 높이는 것이다. 이렇게 할경우 코드 품질이 향상된다는 장점이 있고 둘 중에 한명이 이직을 하게 되더라도 다른 한명이 코드 이해도가 있어 프로젝트를 하는데 도움이 된다.
애자일은 요구사항 변화에 민감한 프로세스 모델이라고 했다. 그렇다면 요구사항 변화에 대응하기 위해 애자일은 어떠한 방법을 선택했을까?
Increment 단위의 개발
우선, 요구사항의 변화에 대응하기 위해 개발 단위를 작은 `Increment` 단위로 줄였다. increment는 점진적인 이라는 뜻을 가지고 있는데, 작은 기능 단위로 한 increment를 개발하면 다음 increment를 개발하는 방식으로 개발을 진행하는 것이다.
새로운 요구사항에 생기면, 다음 increment에 해당 내용을 포함시켜 다시 생명주기를 반복하는 방식으로 진행한다.
한 increment에는 소프트웨어 생명주기 프로세스 4단계가 포함되어 있으며, 한 단위가 끝나면 다시 specification 단계로 돌아가 다음 단계를 개발하는 방식으로 진행한다.
따라서, 애자일 프로세스는 소프트웨어 프로세스를 다소, 반복한다는 특징을 가지고 있다.
Customer를 팀에 참여
애자일에서는, 요구사항 변화에 민감하게 대응하기 위해 실제로, 요구사항을 제시하는 `개발자가 아닌` 고객을 프로젝트 팀에 합류시킨다.
해당 customer의 역할은 요구사항을 제시하고 테스트를 진행하는 것이다. 팀에 고객이 있으므로 바로바로 요구사항이 나올 수 있고 베타버전을 실제 테스트해봄으로써 즉각적인 피드백이 가능하다.
그렇다면, 애자일은 절대적으로 좋은방법일까? 그것은 절대 아니다. 애자일 프로세스는 우선, 문서화 과정을 줄였기에, 이해도는 높지만 세부적인 디테일이 정리되어있지 않아 디테일한 specification이 어렵다는 단점이 있다. 따라서, 이해도가 높은 개발자가 이직을 하게 되었을 경우 문서가 부족해서 디테일한 내용을 알아차리는데는 시간이 걸린다는 단점이 있다.
그렇다면, 애자일 프로세스는 어디에 적합할까?
client에 특화된 프로젝트
애자일은 고객의 요구사항을 즉각적으로 반영하는데 특화된 개발방법론이다. 따라서, 범용적이고 대규모 프로젝트엔 적용하기 어렵다. 범용적인 소프트웨어라하면 액셀, 노션과 같이 특정 고객이 있는 소프트웨어가 아니라, 일반적으로 사용되는 소프트웨어를 의미하는데 여기서 제시된 특정 소비자의 요구사항을 즉각즉각 반응하기엔.. 한계가 있다.
( A,B는 잘 쓰고 있는데 C가 불편하다고 다 바꿔줄 수 없는 노릇 )
대규모 프로젝트
또한, 대규모 프로젝트에서 요구사항이 하나가 변경된다면? 관련된 모든 파트들이 요구사항을 수정해 반영해야한다. 작은 요구사항 대비 들여야하는 비용이 크며, 들인다고해서 절대적으로 좋은 방법도 아니다.
애자일과 Plan-driven 방식의 특징을 비교한 표를 보면 다음과 같다.
실무에서는 어떻게 쓰일까?
두 프로세스 모델의 장단점이 명확히 존재하는데 실무에서는 하나만을 사용하는 것이 아닌, 서브시스템, 컴포넌트 단위로 두 방식을 혼합해서 사용한다. 다만, 프로젝트 특성에 따라서 선택하는 방식이 구분되기도 한다.
가령, 자율주행차를 개발하는데 애자일 프로세스를 선택한다고 해보자. 애자일 프로세스는 일단 개발을 진행하고 요구사항을 피드백 받는 방식인데 애자일을 적용하게 되면,, 사고가 일어난 후에 고치겠다는 뜻과 다름이 없다. 따라서, 이 경우에는 Plan - driven 방식이 더 적절하다.
반대로, UI/UX와 같은 피드백이 즉각적으로 반영되어야하는 프로젝트에서는 애자일 프로세스가 더 적합하다.