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

[소프트웨어공학] 소프트웨어 프로세스 4 (프로세스 활동)

by 사당동호랭이 2023. 8. 2.

 4.3 프로세스 활동

 네 가지 기본적인 활동, 즉 명세화, 개발, 검증, 진화는 개발 프로세스마다 다르게 적용될 수 있다. 폭포수 모델에서 프로세스는 연속적으로 적용되지만 진화적인 개발에서는 서로 중첩되어 적용된다. 이러한 활동들이 어떻게 실행되느냐 하는 것은 소프트웨어, 사람, 조직 구조에 따라 다르다. 이러한 활동을 적용하는 데 올바른 방법은 없으며, 이 절의 목적은 어떻게 적용할 수 있느냐를 소개하는 것이다.

 

 

 

 4.3.1 소프트웨어 명세화

 소프트웨어 명세화 혹은 요구 공학(requirements engineering)은 시스템에서 요구되는 서비스를 정의하고 이해하며, 시스템 운영, 개발의 제약을 찾아내는 프로세스이다. 요구 공학은 이 단계에서의 오류가 시스템 설계와 구현 시의 문제를 야기하기 때문에 특히 중요한 단계이다.

 요구 공학 프로세스는 시스템의 명세서인 요구 문서가 만들어지도록 유도한다. 요구사항은 이 문서에 두 단계로 나타낸다. 최종 사용자와 고객은 요구사항에 대한 고수준의 문장이 필요하고, 시스템 개발자는 좀 더 상세한 시스템 명세가 필요하다. 요구 공학 프로세스에는 다음과 같은 네 가지 단계가 있다.

 

 1. 타당성 조사 : 식별된 사용자의 요구가 현재 사용되고 있는 하드웨어와 소프트웨어 기술을 사용하여 만족될 수 있는지에 대한 평가가 이루어진다. 이 조사는 제안된 시스템이 현재의 예산 범위 내에서 개발될 수 있는지와 비즈니스 관점에서 비용 효과가 있는지를 고려한다. 타당성 조사는 비교적 비용이 적게 들고, 신속하게 진행된다.

 2. 요구사항 추출과 분석 : 이것은 기존의 시스템 관찰과 사용자, 구매자, 위험 분석 등과 같은 사항을 관찰하여 시스템 요구사항을 유도하는 과정이다. 이것은 하나 이상의 시스템 모델과 프로토타입의 개발을 포함할 수 있다. 이것은 분석가로 하여금 분석될 시스템을 이해하는 데 도움을 준다.

 3. 요구사항 명세화 : 분석 활동 동안에 수집된 정보를 요구사항의 집합을 정의한 문서로 변환하는 활동이다. 두 가지 종류의 요구사항이 이 문서에 포함된다. 사용자 요구사항은 고객과 시스템의 최종 사용자를 위한 시스템 요구사항에 대한 추상적 기술이며, 시스템 요구사항은 제공될 기능에 대한 좀 더 상세한 기술을 포함한다.

 4. 요구사항 검증 : 이 활동은 요구사항의 실현가능성, 일관성, 완전성을 검사한다. 이 프로세스 동안 요구사항 문서 내에 있는 오규가 발견된다. 오류는 반드시 수정되어야 한다.

 

 물론 요구 공학 프로세스의 활동은 단순히 엄격하게 순서대로 수행되지 않는다. 요구 분석은 정의, 명세화 동안에도 계속되며, 새로운 요구사항이 프로세스 중간에 생길 수도 있다. 그러므로 분석, 정의 명세화 활동은 서로 중복된다. 익스트림 프로그래밍과 같은 애자일 방법에서 요구사항은 사용자 우선순위에 따라 점증적으로 개발되며, 요구사항 추출은 개발팀의 구성원이 할 수 있다.

 

 4.3.2 소프트웨어 설계와 구현

 소프트웨어 개발의 구현 단계는 시스템 명세서를 실행가능한 시스템으로 변환하는 프로세스이다. 그것은 소프트웨어 설계와 구현을 포함하지만, 만약 진화적인 방법이 사용된다면 소프트웨어 명세서의 정제도 포함된다.

 소프트웨어 설계는 구현될 소프트웨어 구조, 시스템의 일부분인 데이터, 시스템 컴포넌트 간의 인터페이스, 사용될 알고리즘에 대한 기술이다.설계자는 한 번에 설계를 완결하지 못하고 여러 번에 걸쳐서 설계를 개발하게 된다. 설계 프로세스는 초기의 설계를 수정하기 위해 반복적으로 상세함과 정형성을 추가해야 한다.

 설계 프로세스는 추상화 수준에 따라 여러 개의 모델을 개발할 수 있다. 설계가 분할됨에 따라, 앞 단계에서의 오류와 생략된 부분이 발견된다. 이러한 피드백은 초기의 설계 모델이 개선되도록 해 준다. 아래 그림은 설계 단계에서 생성될 수 있는 설계 문서에 대한 것을 나타내는 프로세스 모델이다. 이 다이어그램은 설계 프로세스 단계가 순차적이라는 것을 나타낸다. 사설 설계 프로세스 활동은 서로 중복된다. 한 단계에서 다음 단계로의 피드백과 계속적인 설계는 설계 프로세스에서 필연적인 활동이다.

 다음 단계를 위한 명세서는 각 설계 활동의 산출물이다. 이 명세서는 추상적이며, 요구사항을 분명하게 하기 위한 정형 명세, 혹은 시스템의 일부가 어떻게 구체화되는가에 대한 명세일 수 있다. 설계 프로세스가 진행됨에 따라, 이러한 명세서가 좀 더 상세해진다. 이 프로세스의 최종 결과는 알고리즘과 데이터 구조에 대한 좀 더 정확한 명세이다.

 구체적인 설계 프로세스 활동은 다음과 같다.

 

 1. 아키텍처 설계 : 시스템을 구성하는 서브시스템과 그것의 관계가 식별되고 문서화된다.

 2. 추상 명세화 : 각 서브시스템에 대해서, 그것의 서비스에 대한 추상 명세의 운영상의 제약 조건이 만들어진다.

 3. 인터페이스 설계 : 각 서브시스템에 대해 다른 서브시스템과 그것의 인터페이스가 설계되고, 문서화된다. 서브시스템 운영에 관한 지식이 없어도 이 인터페이스 명세를 사용할 수 있도록 반드시 모호성이 없어야 한다. 

 4. 컴포넌트 설계 : 컴포넌트에 할당된 서비스와 그 컴포넌트의 인터페이스가 설계된다. 

 5. 데이터 구조 설계 : 시스템 구현 시 사용될 데이터 구조가 상세하고 구체적으로 설계 된다.

 6. 알고리즘 설계 : 서비스를 제공하기 위해서 사용되는 알고리즘이 상세하고 구체적으로 설계된다.

 

 이것은 설계 프로세스의 일반적인 모델이고 실제 프로세스는 다른 방법으로 응용될 수 있다. 가능한 응용 방법은 다음과 같다.

 

 1. 설계의 마지막 두 단계인 데이터 구조와 알고리즘 설계는 구현 프로세스까지 지연될 수 있다.

 2. 만약 실험적인 방법이 사용된다면, 시스템 인터페이스는 데이터 구조가 정의된 후에 설계 될 수 있다.

 3. 추상 명세화 단계는 중대한 시스템 설계의 필수적인 요소이기는 하지만 생략될 수 있다.

 

 애자일 개발 방법이 사용되는 곳에서는 설계 프로세스의 결과가 분리된 명세서가 아니라 프로그램의 코드로 표현된다. 시스템 아키텍처가 설계된 후에 설계의 다음 단계가 추가된다. 각 증분은 설계 모델보다는 프로그램 코드로 표현된다.

 구조적 설계 기법에서 채택된 접근법은 대조적으로 시스템의 그래픽 모델을 만드는데 의존하는 설계이며 많은 경우에 이 모델로부터 코드를 자동적으로 생성한다. 구조적 방법은 1970년대에 기능 지향 설계를 지원하기 위해서 개발되었다. 객체 지향 설계를 지원하기 위한 여러 가지 방법이 제안되었으며, 이것은 UML(Unified Modeling Language)과 관련된 통합 설계프로세스를 만들기 위해서 통합되었다.

 구조적 방법은 설계, 보고서 형식, 규칙, 설계 지침을 표현하기 위한 표기법과 설계 프로세스 모델을 포함한다. 구조적 방법은 시스템의 다음과 같은 모델의 전부 혹은 일부분을 포함한다.

 

 1. 시스템에서 사용된 객체 클래스 및 객체 클래스 간의 의존성을 나타내는 객체 모델

 2. 시스템이 실행될 때 시스템에서 어떻게 객체가 서로 작용하는지를 보여주는 순차모델

 3. 시스템의 상태 및 한 상태에서 다른 상태로의 전이를 나타내는 상태 전이 모델

 4. 시스템 컴포넌트 및 컴포넌트의 집합에 관한 문서인 구조 모델

 5. 데이터가 처리됨에 따라 생기는 데이터 변환을 사용하여 시스템이 모델링 되는 테이터 흐름 모델. 이것은 보통 객체 지향 방법에서는 사용되지 않지만 실시간과 비즈니스 시스템 설계에서는 여전히 자주 사용된다.

 

 

 실제로, 구조적 '방법'은 표준적인 표기법이며 좋은 실무 관행이 구체화된 것이다. 이 방법과 지침을 따르면 좋은 설계를 할 수 있다. 설계자의 창의성은 시스템의 분할을 결정하고 시스템이 적절하게 시스템의 명세를 반영했는지를 확인하기 위해서 요구된다. 설계자에 관한 실험적 연구에 의하면 구조적 방법을 그대로 거의 따라 하지 않는다. 설계자들은 지역적인 환경에 맞게 필요한 지침만 선택한다.

 시스템 설계 프로세스 다음에는 시스템을 구현하기 위한 양식의 개발이 뒤따른다. 안전성 중심 시스템과 같은 어떤 부류의 프로그램은 구현이 시작되기 전에 상세하게 설계되지만 설계의 후반과 프로그램 구현이 서로 교차되어 가는 것이 보통이다. CASE 도구가 설계로부터 골격 코드를 생성하기 위해서 사용된다. 이것은 인터페이스를 정의하고 구현하는 코드를 포함하며 각 프로그램 컴포넌트의 오퍼레이션을 추가하기만 하면 된다.

 프로그래밍은 개인적인 활동이며 따라야 할 일반적인 프로세스는 없다. 어떤 프로그래머는 그들이 잘 알고 있는 컴포넌트부터 시작하여 덜 익숙한 컴포넌트로 옮겨간다. 다른 사람은 그들의 잘 알고 있는 컴포넌트부터 시작하여 덜 익숙한 컴포넌트로 옮겨간다. 다른 사람은 그들이 어떻게 개발하는지를 파악할 수 있을 때까지 친숙한 컴포넌트는 그대로 두는 반대의 방법을 취한다. 어떤 개발자는 초기에 데이터를 정의하고 그것을 프로그램 개발에 사용하고 반대로 데이터는 정의하지 않고 가능한 한 그대로 두는 경우도 있다.

 보통의 경우에 프로그래머는 그들이 개발한 코드를 시험한다. 이것은 프로그램으로부터 제거해야 할 결점을 찾아내는 과정이다. 이것을 디버깅이라고 한다. 결점 시험과 디버깅은 상이한 프로세스이다. 시험은 결점의 존재를 확인하는 것이지만, 디버깅은 결점의 위치를 찾아 수정하는 것과 관계가 있다.

 디버깅 프로세스는 오류발견 -> 오류수정 설계 -> 오류 수정 -> 프로그램 재시험 같이 디버깅 단계에 대한 예시이다. 코드상에서의 결점을 찾아내고 명세서와 일치하도록 프로그램을 수정한다. 시험은 변경이 정확하게 되었는지를 보충하기 위해서 반복된다. 따라서 디버깅 프로세스는 소프트웨어 개발과 소프트웨어 시험의 일부분이다.

 디버깅을 할 때 프로그램의 관찰가능한 동작에 대한 가설을 세우고 나서 이상이 있는 출력을 야기한 결점을 찾는다는 생각으로 가설을 시험한다. 가설을 시험할 경우 수작업으로 프로그램 코드를 추적하는 경우도 있다. 문제를 찾기 위해서 새로운 시험 사례를 작성해야 한다. 프로그램 변수의 중간 값을 보여주는 대화식의 디버깅 도구와 실행하는 문장을 추적하는 도구가 디버깅 프로세스를 돕기 위해 사용된다.