본문 바로가기
CS/소프트웨어공학

[소프트웨어공학] Chapter 2 - Software Process and Methodology

by 경험의 가치 2024. 3. 18.

해당 책을 바탕으로 글을 작성하였습니다

 

시스템 개발의 어려움

  • 학부에서 소프트웨어 개발하는 것과 현업에서 개발하는 것은 큰 차이를 가지고 있음. 어떤 차이가 있어야 소프트웨어 프로세스와 방법론이 필요한지 이해할 수 있음.
  1. 많은 프로젝트들은 1년에서 몇년까지 아주 긴 개발 기간을 지니고 있음. 그렇기 때문에 향후 몇년간 어떤일이 일어날 것이고, 이를 어떻게 대비할 것인지 계획해야 함.
  2. 많은 프로젝트들은 다른 부서 또는 팀과 협업을 통해 개발이 이루어지는 경우가 많음. 따라서, 어떻게 상호 의존적인 부분으로 팀에게 할당하고, 이를 원활하게 합칠 수 있을까 생각해야됨. 예를 들어, 어떤 시스템을 개발한다 치면 백엔드 부서와 프론트 엔드 부사가 각각 나누어 개발하고, 이를 나중에 합쳐서 하나의 서비스로 운용해야됨.
  3. 부서 또는 팀들이 각기 다른 개발 프로세스, 방법, 도구들을 이용하는 경우가 많음. 그렇기 때문에 이러한 다른 개발 방법 사이에서 어떻게 원활하게 소통해야 할지 고민해야됨.
  4. 현업에서는 엄격한 실시간 필요 사항이나 제약이 적용됨. 예를 들어, 메일 처리 시스템을 개발한다 치면, 1시간에 40000개 이상, 초당 12개 이상의 메일을 처리해야됨. 이런 요구사항을 충족시키는 시스템을 어떻게 개발할 수 있을까에 대한 고민이 필요함.
  5. 요구사항은 시간에 따라서 계속해서 변화함. 이런 예측 불가능한 요구사항의 변화를 적절히 수용할 수 있도록 개발이 가능한지 고민해야함.
  6. 시스템은 몇년에 걸처서 진화하고 이 과정에서 유지보수 문제를 야기함. 시스템에 변화는 버그를 발생시킬 뿐만 아니라, 시스템 구조를 악화시킬 수 있음. 따라서, 어떻게 하면 쉽게 시스템이 버그나 구조 악화 등 타격을 발생시키지 않고 변화시킬 수 있을지 고민해야함.
  7. 시스템은 소프트웨어와 하드웨어로 구성되어 있을 것이고, 서드파티 요소나 다양한 언어로 개발되있을 것이며, 여러 플랫폼에 대해서 돌아가야 할 것임. 따라서, 이러한 하드웨어, 플랫폼, 언어 등의 의존성을 숨기고, 이러한 의존성이 시스템에 영향이 없도록 어떻게 디자인 해야되는지 고민해야 함.

 

소프트웨어 프로세스

  • 소프트웨어 프로세스 : 소프트웨어 시스템을 만들기 위해서 각 단계별로 행해지는 일련의 활동들의 과정. 각각 소프트웨어 프로세스의 단계는 어떤 부산물을 만들어내고, 이는 다른 단계의 입력이 됨. 각각 단계는 일련의 입력과 출력 기준이 존재함

 

Waterfall 방식의 이점과 문제점

장점

  • 간단하고 곧은 방식을 통해 프로젝트 계획, 스케쥴링, 상태 추적 등을 쉽고 간단하게 예측할 수 있도록 도와줌. 즉, 각 단계 별로 어떤 결과가 나올지 예측이 가능해짐.
  • 기능 중심의 프로젝트 구성을 가능하게 함. 예를 들어, 팀에서 요구사항 분석 팀, 디자인팀, 구현팀 등 기능 중심으로 나누어서 개발할 수 있음.
  • 크고 복잡하고 오래 지속되는 임베디드 시스템에 적합함. 예를 들어, 메일 시스템이나 라우팅 시스템이나 프로세스 컨트롤 시스템들은 수많은 하드웨어에서 발생할 이벤트들, 많은 양에 들어오는 데이터들에 응답해야하며, 하드웨어 장치들을 컨트롤 해야함. 그리고 보통 이런 시스템의 요구사항 및 실현 가능성 분석은 장비 제조업체에서 이루어짐. 게다가 보통 이런 임베디드 시스템들은 주요 요구사항이 바뀌는 경우가 잘 없음. 따라서, waterfall 방식을 통하여 시스템의 안정성이나 성능 및 시간 제약 등을 충족시킬 수 있게 되는 것.

단점

  • 엄격한 단계별 요구사항으로 인하여 변화에는 대응이 어려움
  • 시스템이 출시 될때까지 유저 피드백을 받을 수 없음
  • 긴 개발기간 동안, 유저들은 이 시스템을 접할 수 없기 때문에, 새로운 시스템에 대한 이점을 전혀 알 수 가 없음.
  • 개발 기간이 매우 길기 때문에, 프로젝트가 망하면 그에 따른 위험이 매우 큼.

 

소프트웨어 개발은 Wicked Problem

  • wicked problem은 문제를 명확히 정의할 수 없어서 해결하기가 어려운 문제들을 의미함. Tame Problem과 반대되는 말임(문제를 명확하게 정의하고 풀 수 있는 것)
  • 소프트웨어 개발 과정은 일반적으로 wicked problem임
  • 필요사항 요구분석이 실제 요구사항을 충족시키지 못하는 경우도 있음. 실제로 이래서 많은 프로젝트들이 실패를 함.
  • 프로토타입은 이 실제 요구사항을 분석하기 위해서 만들어지는 것임
  • 소프트웨어 시스템은 평생 테스트가 필요함. 오타 같은 사소한 문제가 몇십년 뒤에 큰 문제를 야기할 수도 있음. 즉, 오류가 있음을 바로 인지하기가 어려움
  • 소프트웨어 개발은 과학적인 프로세스가 아님. 즉, 정치적이고 경제적인 프로세스로 이해해야됨. 예를 들어, 유지보수의 비용 문제 때문에 최적의 알고리즘 보다, 적당한 알고리즘을 선택하는 경우가 있음.

 

Software Process 모델들

Prototyping Process

  • 앞서 언급했던 것 처럼, 우리가 요구사항 분석에서 생각한 것과 실제 요구사항은 다를 수 있음
  • 따라서 프로토타입을 만듦으로써 사용자들의 실제 기대와 요구사항에 대한 일치를 체크해볼 수 있음
  • 간단한 프로토타입 모델 : 우리 시스템이 유저들이랑 어떻게 상호작용 하는지 간단한 스크린샷이나 스캐치 정도로 보여줌
  • 정교한 프로토타입 모델 : 시스템 기능들이 실제 수행되는 것을 보여줌

Evolutionary Process

  • 정교한 프로토타입을 만드는데는 노력이 낭비될 여지가 있음
  • 프로토타입을 진화시킴으로써 이런 노력 낭비 문제를 해결함
  • 초기 프로토타입을 만들고, 이걸 유저들에게 보여준 후, 피드백을 바탕으로 프로토타입을 발전 시킴. 이러한 과정의 반복을 통해 발전된 모델을 만듦.
  • 이 방식은 탐색적 자료 분석을 해야되는 프로젝트들에 적합함. 예를 들어, 시스템에 가장 정확한 요구사항이나 알고리즘들을 활용해야 하는 프로젝트들.
  • 이 방식은 미래에 기대되는 결과를 예측해서 개발해야 하는 프로젝트들에게는 부적합함.

Spiral Process

  • 시스템 개발시 위험을 최소화 하기 위해 점진적으로 완벽한 시스템으로 개발해 나가는 모델
  1. Determine the objective (목표 설정) : 현재 사이클에 대하여 목표, 대안, 제약을 설정함.
  2. Risk Analysis (위험 분석) : 예측되는 위험 사항에 대해 추출하고 이에 대한 대안을 수립하는 단계.
  3. Development&Test (개발 및 검증) : 구축하려는 시스템과 개발 환경에 맞는 개발 모델을 선택함. (ex : Waterfall, Prototyping Model 등)
  4. Evaluation/Plan next phases (고객 평가 및 다음 단계 수립) : 개발과 테스트가 끝난 내용을 고객이 평가하여, 이 과정을 추가 반복할 여부를 정함

Unified Process (UP 방법론)

  • 소프트웨어를 반복/점진적으로 개발하고, 각 사이클마다 시스템의 출시로 끝이
  • Inception, Elaboration, Construction, Transition 단계로 각각 이루어짐.
  • 각각 단계에서 요구사항 분석/설계/구현/테스트/배포 작업들을 병렬적으로 함
  • Inception : 간단하게 use case를 분석하고, 시험적인 소프트웨어 아키택처를 도입하며, 프로젝트 계획을 짬. 간단하게 시스템을 기획하는 부분임
  • Elaboration : use case를 구체화 하고, UML을 그리며, 구체적인 아키택처 디자인을 짜는 부분
  • Construction : use case들을 시스템에 구현하고 통합함
  • Transition : 유저들에게 베타 테스트를 하고, 배포를 함

Agile Process (애자일 개발론)

  • wicked problem을 해결하고자 고안된 프로세스
  • 애자일 방법론은 팀워크를 강조하며, 유저와 개발자가 상호작용 하며 개발하고, 빠르게 개발하도록 도움
  • 작업 계획을 짧은 단위로 세우고, 제품을 만들고, 고쳐나가는 사이클을 반복함으로써 고객의 요구 변화에 유연하고도 신속하게 대응하는 개발 방법론
  • 애자일 방법론은 아래 애자일 소프트웨어 개발 선언문의 가치를 둔다.
    1. 프로세스와 툴보다는 개인과 상호작용이 우선이다 : 프로젝트의 성공을 위해서 개개인의 능력 또한 중요하다. 하지만, 그것보다 팀원간의 의사소통을 통해서 동료와 조화롭게 일하는 것이 훨씬 더 중요하다. 또한, 개발툴도 지나치게 거대한 툴이 아닌, 자신이 잘 이해하고 사용할 수 있는 개발툴을 사용해야 한다. 예를 들어 UML도 OO 디자인에 대한 상식이 있어야 잘 쓸 수 있다.
    2. 포괄적인 문서보다는 동작하는 소프트웨어가 더 중요하다 : 개발할 때, API 명세서와 같이 코드는 시스템 구조에 대해 의사소통 하기 위해서 문서화되어야 한다. 하지만, 지나친 문서화는 작성 시간이 많이 들고, 동기화를 유지하는데 많은 비용을 야기한다. 즉, 문서는 짧고 간결하게 요약적으로 정리해야 한다.
    3. 계약 협상보다는 고객 협력이 우선이다 : 클라이언트와 계약을 채결하고 끝이 아닌 그때 부터가 진짜 시작이다. 계속해서 고객과 협력해서 규칙적으로 피드백을 받아야 하고, 발전시켜 나가야 한다.
    4. 계획을 따르는 것 보다 변화에 대한 반응이 우선이다 : 계획에 집착하는 것이 아닌 변화에 유연하게 대처할 수 있는 방법이 되어야 한다. 개발을 하다보면 트랜드는 바뀌고, 요구사항이 바뀐다. 즉, 우리는 소프트웨어 프로젝트의 최종 목표를 예상할 수 없고 계획은 계속 바뀔 것이다. 처음부터 끝까지 세부 계획을 상세하게 짜두면, 변화에 대처하기 힘들고, 따라서 가까운 시일 내 일에 대해서만 세부적이게 계획을 짜고, 나머지는 탄력적으로 조정해야 한다.
  • 애자일 원칙
    1. 적극적인 사용자 참여는 필수적이다 : 고객들의 실제 기대와 요구사항을 알아내고, 변화에 대응하기 위해서는 적극적인 사용자들의 피드백이 필수적이다.
    2. 팀은 반드시 의사결정을 내릴 수 있는 권한이 있어야 한다 : 애자일 방법론은 개개인들 간에 상호작용과 의사소통을 아주 중요시한다. 즉, 팀 맴버들은 프로젝트에 대해서 의사결정을 내릴 수 있어야 한다.
    3. 요구사항은 늘어나지만, 기간은 정해져있다 : 실제 개발에서 요구사항은 개발함에 따라 점차 증가하고 변화한다. 하지만 우리들의 개발 기간은 정해져있다. 따라서, 새로운 요구사항들은 다른 요구사항들의 비용을 고려하여 수용되어야 한다. 즉, 중요한 것이 아닌 이상 새로운 요구사항을 위해 다른 요구사항을 포기하기도 해야한다.
    4. 높은 수준의 요구사항을 잡아라 (가볍고 시각적이게) : 요구사항을 유저들의 스토리, use case, 특징, 스토리보드 등 가볍고 시각적이고 쉽게 볼 수 있도록 공유해야한다. 즉, 지나친 포괄적인 문서화가 아닌 짧고 간결하고 요약적이게 정리해야 한다.
    5. 점진적으로 개발하고 이를 반복해라 : 애자일 방법론은 개발 및 배포가 점진적으로 반복해서 일어나야 한다. 그래야 유저들의 피트백을 수용하기 쉽고, 프로젝트 실패 리스크를 줄일 수 있다.
    6. 소프트웨어를 지속적으로 공개하는 것에 초점을 맞춰라 : 개발중인 소프트웨어를 짧게는 2주, 길게는 2달 정도 시간 간격으로 자주 공개해야 한다.
    7. 다음 단계로 넘어가기 전에 현재 개발하고 있는 각각의 기능을 완성해라 :
      다음 단계로 넘어가기 전에 현재 개발하고 있는 기능을 100% 완전히 개발하고 넘어가라. 이를 위해서 TDD (Test Driven Development)를 이용한다. 작은 단위로 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다. TDD는 실패하는 테스트 코드 작성 → 테스트 코드를 성공시키기 위한 실제 코드 작성 → 중복 코드 제거 및 일반화 등의 리펙토링 과정으로 반복적으로 진행된다.
    8. 80 - 20 룰을 적용해라 : 최상의 결과가 아닌 적당히 적합한 것을 채택하라는 말이다. 80:20 법칙이란 80%의 결과가 20%의 원인에 의해 발생한다는 것이다. (파레토 법칙이라고도 불림) 즉, 우리는 개발할 때 20%의 요구사항에 전념하여 80%의 결과를 만들어 내야 한다는 것.
    9. 테스트는 프로젝트의 전반적인 과정에 통합되어야 한다 : 테스트는 일찍 그리고 자주 해야한다. 5~7번 법칙이랑 비슷한 내용이다. JUnit같은 유닛 테스트 라이브러리를 통해서 지속적으로 테스트가 이루어질 수 있도록 해야한다.
    10. 모든 이해관계자들의 협조적이고 협력적인 접근은 필수적이다 : 전통적인 개발 방식은 포괄적인 문서만 가지고 개발팀들이 의사소통 했다. 하지만, 시스템의 모든 이해 관계자들, 즉 모든 고객들과 개발 팀들 등등이 서로를 이해하고 다같이 일하며 협력해야 한다.