소프트웨어 구축

소프트웨어 구축(software construction)은 코딩과 통합을 통해 작동하는 소프트웨어를 만드는 과정이다. 이 과정에는 단위 및 통합 테스트가 포함되지만, 시스템 테스트와 같은 높은 수준의 테스트는 포함되지 않는다.SWEBOK 

구축은 소프트웨어 개발 수명 주기의 한 측면이며, 다른 활동과 분리된 활동으로서 구축에 대한 다양한 초점을 가진 여러 소프트웨어 개발 프로세스 모델에 통합된다. 폭포수 모델에서 소프트웨어 개발 노력은 구축을 시작하기 위한 전제 조건인 요구사항 분석, 설계, 계획을 포함하는 순차적인 단계로 구성된다. 스크럼, 진화적 프로토타이핑 또는 익스트림 프로그래밍과 같은 반복적 모델에서는 구축이 다른 활동과 동시에 또는 겹쳐서 발생하는 활동이다.

구축 계획에는 구성 요소가 생성되고 통합되는 순서, 소프트웨어 품질 관리 프로세스, 팀 및 개발자에게 작업 할당을 정의하는 것이 포함될 수 있다.

프로젝트 관리를 용이하게 하기 위해 개발된 코드의 양, 수정된 코드, 재사용된 코드, 파괴된 코드, 코드 복잡성, 코드 검사 통계, 오류 수정 및 발견률, 투입된 노력 등 수많은 구축 측면을 측정할 수 있다. 이러한 측정은 품질 보장 및 프로세스 개선과 같은 측면에 유용할 수 있다.

 활동 
구축에는 많은 활동이 포함된다.

 코딩 
다음은 코딩 활동의 몇 가지 주요 측면이다.

 명명
각 식별자에 대한 이름 선택. 한 연구에 따르면 변수 이름이 10자에서 16자 사이일 때 프로그램 디버깅에 필요한 노력이 최소화된다.

 로직
문 및 루틴으로 구성
 응집력이 높은 루틴은 응집력이 낮은 루틴보다 오류 발생률이 낮은 것으로 입증되었다. 450개 루틴에 대한 연구에 따르면 응집력이 높은 루틴의 50%는 오류가 없었지만, 응집력이 낮은 루틴의 18%만이 오류가 없었다. 다른 450개 루틴에 대한 또 다른 연구에 따르면 결합도 대비 응집도 비율이 가장 높은 루틴은 가장 낮은 루틴보다 오류가 7배 많고 수정 비용이 20배 더 많이 드는 것으로 나타났다.
 연구에서 루틴 크기와 오류 발생률 간의 상관 관계에 대한 확실한 결과는 나오지 않았지만, 한 연구에서는 143줄 미만의 코드 라인을 가진 루틴이 더 큰 루틴보다 수정 비용이 2.4배 적게 드는 것으로 나타났다. 또 다른 연구에서는 루틴이 평균 100~150줄의 코드일 때 코드를 가장 적게 변경해야 한다고 밝혔다. 또 다른 연구에서는 루틴의 크기와 관계없이 구조적 복잡성과 데이터 양이 오류와 관련이 있음을 발견했다.
 루틴 간의 인터페이스는 프로그램에서 오류가 가장 많이 발생하는 영역 중 일부이다. 한 연구에 따르면 모든 오류의 39%가 루틴 간의 통신 오류였다.
 사용되지 않는 매개변수는 오류율 증가와 관련이 있다. 한 연구에서 참조되지 않은 변수가 2개 이상인 루틴의 17%~29%만이 오류가 없었지만, 사용되지 않는 변수가 없는 루틴에서는 46%가 오류가 없었다.
 루틴의 매개변수 수는 최대 7개여야 한다. 연구에 따르면 사람들은 일반적으로 한 번에 약 7개 이상의 정보 덩어리를 추적할 수 없기 때문이다.
 한 실험에 따르면 배열에 무작위로 접근하는 대신 순차적으로 접근하는 설계는 변수가 적고 변수 참조도 적다.
 한 실험에 따르면 exit이 있는 루프가 다른 종류의 루프보다 더 이해하기 쉽다.
 루프와 조건문의 중첩 수준에 관해서는 프로그래머가 3단계 이상의 중첩을 이해하기 어렵다는 연구 결과가 있다.
 제어 흐름 복잡성은 낮은 신뢰성과 빈번한 오류와 관련이 있는 것으로 나타났다.

 모듈성
코드를 클래스, 패키지 및 기타 구조로 구성하고 리팩터링한다. 포함을 고려할 때 클래스의 최대 데이터 멤버 수는 7±2를 초과해서는 안 된다. 연구에 따르면 이 숫자는 사람이 다른 작업을 수행하면서 기억할 수 있는 이산 항목의 수이다. 상속을 고려할 때 상속 트리의 수준 수는 제한해야 한다. 깊은 상속 트리는 오류 발생률 증가와 유의미하게 관련이 있는 것으로 밝혀졌다. 클래스에 있는 루틴의 수는 가능한 한 적게 유지해야 한다. C++ 프로그램에 대한 연구에서 루틴 수와 오류 수 사이에 연관성이 발견되었다. NASA의 한 연구에 따르면 코드를 잘 구성된 클래스에 넣으면 기능 설계를 사용하여 개발된 코드에 비해 코드 재사용성이 두 배로 늘어날 수 있다.

 오류 처리
계획된 오류와 계획되지 않은 오류 및 예외를 처리하기 위한 로직 인코딩.

 자원 관리
쓰레드 또는 데이터베이스 락을 포함하여 배타적 메커니즘 및 직렬 재사용 자원 접근의 규율을 통해 연산 자원 사용을 관리한다.

 보안
버퍼 오버런 및 배열 인덱스 오버플로와 같은 코드 수준의 보안 침해 방지.

 최적화
최적화와 동시에 조기 최적화를 피한다.

 문서화
주석으로 코드에 포함된 것과 외부 문서로 작성된 것 모두.

 통합 
통합은 별도로 구성된 부분을 결합하는 것이다. 고려 사항에는 구성 요소가 통합될 순서 계획, 소프트웨어의 임시 버전을 지원하는 스캐폴딩 생성, 구성 요소가 통합되기 전에 수행되는 테스트 및 품질 작업 정도 결정, 임시 버전이 테스트되는 프로젝트의 시점 결정 등이 포함된다.

 테스트 
테스트는 코드에 잘못된 로직이 삽입된 시점과 탐지된 시점 사이의 시간을 줄일 수 있다. 어떤 경우에는 코드가 작성된 후에 테스트가 수행되지만, 테스트 우선 프로그래밍에서는 코드를 작성하기 전에 테스트 케이스를 생성한다. 구축에는 최소 두 가지 형태의 테스트가 포함되며, 종종 코드를 작성한 개발자가 수행한다. 유닛 테스트 및 통합 테스트.

 재사용 
소프트웨어 재사용은 라이브러리를 만들고 사용하는 것 이상을 포함한다. 소프트웨어 수명 주기에 재사용 프로세스 및 활동을 통합하여 재사용 관행을 공식화해야 한다. 코딩 및 테스트 중 소프트웨어 구축에서 재사용과 관련된 작업에는 다음이 포함될 수 있다. 재사용 가능한 코드 선택, 코드 또는 테스트 재사용성 평가, 재사용 지표 보고.

 품질 보장 
소프트웨어를 구축할 때 품질을 보장하기 위한 기술은 다음과 같다.

 테스트
한 연구에 따르면 유닛 테스트와 통합 테스트의 평균 결함 감지율은 각각 30%와 35%이다.

 소프트웨어 검사
소프트웨어 검사에 관해서는 한 연구에서 공식 코드 검사의 평균 결함 감지율이 60%인 것으로 나타났다. 결함 발견 비용에 관해서는 코드 읽기가 테스트보다 시간당 80% 더 많은 결함을 감지한다는 연구 결과가 있다. 또 다른 연구에서는 테스트를 사용하여 설계 결함을 감지하는 것이 검사를 사용하는 것보다 6배 더 많은 비용이 든다는 것을 보여주었다. IBM의 한 연구에서는 코드 검사를 통해 결함을 찾는 데 3.5시간이 걸렸지만, 테스트를 통해서는 15~25시간이 걸렸다. 마이크로소프트는 코드 검사를 사용하여 결함을 찾고 수정하는 데 3시간이 걸리고 테스트를 사용하여 결함을 찾고 수정하는 데 12시간이 걸린다는 것을 발견했다. 70만 줄의 프로그램에서 코드 검토가 테스트보다 여러 배 더 비용 효율적이라는 보고가 있다. 연구에 따르면 검사는 비공식적인 검토 관행보다 코드 1000줄당 결함 수를 20%~30% 줄이고 생산성을 약 20% 증가시킨다. 공식 검사는 일반적으로 프로젝트 예산의 10%~15%를 차지하며 전체 프로젝트 비용을 줄일 것이다. 연구자들은 공식 검사에 2~3명 이상의 검토자를 두는 것이 발견되는 결함 수를 증가시키지는 않지만, 결과는 검사되는 자료의 종류에 따라 달라지는 것으로 보인다.

 기술 검토
기술 검토에 관해서는 한 연구에서 비공식 코드 검토 및 데스크 검사의 평균 결함 감지율이 각각 25%와 40%인 것으로 나타났다. 워크스루는 결함 감지율이 20%~40%였지만, 특히 프로젝트 압력이 증가할 때 비용이 많이 드는 것으로 나타났다. NASA는 코드 읽기가 시간당 3.3개의 결함을 감지하는 반면, 테스트는 시간당 1.8개의 결함을 감지한다는 것을 발견했다. 또한 다양한 종류의 테스트보다 프로젝트 수명 동안 20%~60% 더 많은 오류를 발견한다. 검토 회의에 대한 13개 검토 연구에서 결함의 90%가 검토 회의 준비 과정에서 발견되었고 회의 중에는 약 10%만이 발견되었다.

 정적 분석
정적 분석 (IEEE1028)에 관해서는 높은 결함 감지율을 달성하기 위해 이러한 기술을 조합하여 사용해야 한다는 연구 결과가 있다. 다른 연구에서는 다른 사람들이 다른 결함을 찾는 경향이 있다는 것을 보여주었다. 한 연구에서는 익스트림 프로그래밍의 페어 프로그래밍, 데스크 검사, 유닛 테스트, 통합 테스트, 회귀 테스트와 같은 관행이 90%의 결함 감지율을 달성할 수 있다는 것을 발견했다. 숙련된 프로그래머가 참여한 실험에서는 테스트를 통해 15개 오류 중 평균 5개(최대 9개)의 오류를 찾을 수 있었다.

오류의 80%는 프로젝트 클래스와 루틴의 20%에 집중되는 경향이 있다. 오류의 50%는 프로젝트 클래스의 5%에서 발견된다. IBM은 IMS 시스템에서 425개 클래스 중 31개만 수리하거나 다시 작성함으로써 고객 보고 결함을 10분의 1로 줄이고 유지보수 예산을 45% 줄일 수 있었다. 프로젝트 루틴의 약 20%가 개발 비용의 80%를 차지한다. IBM의 고전적인 연구에 따르면 OS/360의 몇몇 오류 발생률이 높은 루틴이 가장 비싼 엔터티였다. 이 루틴은 코드 1000줄당 약 50개의 결함을 가지고 있었고, 이를 수정하는 데 전체 시스템을 개발하는 데 드는 비용의 10배가 들었다.

 재설계 
소프트웨어 설계의 예상치 못한 격차를 설명하기 위해 구축 중에 설계 수정이 이루어질 수 있다.

 언어 
구축에 사용되는 언어 유형은 다음과 같다.
 일반 목적 프로그래밍 언어  가장 유연한 유형의 언어
 구성 언어  개발자가 제한된 옵션 집합에서 선택하여 사용자 지정 소프트웨어 설치를 생성한다.
 툴킷 언어  툴킷으로 응용 프로그램을 구축하는 데 사용된다.

3년 이상 사용한 언어로 작업하는 프로그래머는 해당 언어에 새로 익숙해진 동등한 경험의 프로그래머보다 약 30% 더 생산적이다. C++, 자바, 스몰토크, 비주얼 베이직과 같은 고수준 언어는 어셈블리 및 C와 같은 저수준 언어보다 생산성, 신뢰성, 단순성, 이해도 면에서 5~15배 더 우수하다. 동등한 코드는 저수준 언어보다 고수준 언어로 구현하는 데 더 적은 줄이 필요한 것으로 나타났다.

 모범적 실천 방안 
많은 요소가 소프트웨어 품질에 기여하고 총 소유 비용을 최소화한다.

 복잡성 최소화 
프로그래밍 복잡성을 최소화하는 것은 주로 복잡한 정보를 효과적으로 처리할 수 있는 사람들의 제한된 능력에 의해 좌우된다. 복잡성은 구축 중심 품질 기술을 통해 줄일 수 있다.

 변경 예측 
변경을 예측하는 것은 개발자가 확장 가능한 소프트웨어  즉, 내재된 설계를 방해하지 않고 개선될 수 있는 코드를 구축하는 데 도움이 된다.
25년 이상의 연구에 따르면 재작업 비용은 요구사항을 처음부터 올바르게 파악하는 것보다 10배에서 100배(소규모 프로젝트의 경우 5배에서 10배) 더 비쌀 수 있다. 평균 프로젝트에서 개발 중에 요구사항의 25%가 변경된다는 점을 고려할 때 재작업 비용을 줄여야 할 필요성이 변경 예측의 필요성을 명확히 한다.

 확인을 위한 구축 
검증을 위한 구축은 개발자가 쉽게 결함을 찾아낼 수 있고 독립적인 테스트 및 운영 활동 중에도 결함을 찾아낼 수 있도록 소프트웨어를 구축하는 것을 의미한다. 검증을 위한 구축을 지원하는 특정 기술에는 코드 검토를 지원하기 위한 코딩 표준 준수, 유닛 테스트, 코드를 자동화된 테스트를 지원하도록 구성, 복잡하거나 이해하기 어려운 언어 구조의 제한된 사용 등이 있다.

 정보 은닉 
정보 은닉은 대규모 프로그램에서 유용한 설계 기술로 입증되었으며, 수정이 4배 더 쉬워졌다. 낮은 팬아웃은 연구자들이 유익하다고 밝힌 설계 특성 중 하나이다.

 재사용 
소프트웨어 재사용은 상당한 생산성, 품질 및 비용 이점을 실현할 수 있다. 주요 이점은 기존 소프트웨어 자산을 재사용함으로써 달성되며, 재사용은 미래 재사용을 위해 설계된 소프트웨어를 생성함으로써 지원된다.

 표준 
건축 문제에 직접적인 영향을 미치는 표준(국제 조직에서 만든 외부 표준이든 회사 차원에서 만든 내부 표준이든)은 다음과 같다.
 형식 및 내용에 대한 문서화 표준
 UML과 같은 모델링 표준
 코딩 표준

 데이터 추상화 
데이터 추상화는 구현 세부 정보를 숨기면서 정보의 의미와 유사한 형태로 정보를 나타내는 소스 코드의 특성이다. 학술 연구에 따르면 데이터 추상화는 함수형 프로그램보다 프로그램을 약 30% 더 쉽게 이해할 수 있게 한다.

객체 지향 언어는 데이터 추상화, 캡슐화, 모듈성, 상속, 다형성, 반영과 같이 프로그램의 유연성과 적응성을 높이는 일련의 런타임 메커니즘을 지원한다.

 방어적 프로그래밍 
방어적 프로그래밍은 잘못된 입력으로 인해 루틴이 손상되지 않도록 보호하는 것이다. 어설션은 프로그램의 런타임 검사를 허용하는 프로그램에 배치된 실행 가능한 프레디케이트이다. 계약에 의한 설계는 각 루틴에 선행 조건과 후행 조건을 포함하는 개발 접근 방식이다.

 오류 처리 
오류 처리란 프로그램 실행 시 발생할 수 있는 오류 조건에 대한 코딩 관행을 말한다. 예외 처리는 예외 발생, 즉 프로그램 실행의 정상적인 흐름을 변경하는 특수 조건을 처리하도록 설계된 프로그래밍 언어 구성 또는 하드웨어 메커니즘이다. 결함 허용은 오류를 감지하고 가능하다면 복구하거나 복구가 불가능할 경우 그 영향을 억제하여 소프트웨어 신뢰성을 높이는 기술 모음이다.

 코딩 관점 

 상태 기반 논리 
상태 기반 프로그래밍은 유한 상태 기계를 사용하여 논리를 구현하는 것으로 구성된다.

 테이블 기반 논리 
테이블 기반 논리는 테이블로 형식화된 정보를 사용하여 실행을 구동한다.

 런타임 구성 
런타임 구성은 프로그램이 실행되는 동안 변수 값과 프로그램 설정을 바인딩하는 기술로, 일반적으로 구성 파일을 업데이트하고 읽어서 수행된다.

 국제화 
국제화와 지역화는 여러 로캘을 지원하고 다양한 로캘을 지원하기 위해 프로그램을 준비하는 활동이다.

 같이 보기 
 소프트웨어 공학
 소프트웨어 개발

 내용주 

 각주 



 외부 링크 
 Guide to the Software Engineering Body of Knowledge - 2004 Version By IEEE Computer Society
 Guide to the Software Engineering Body of Knowledge, Version 3.0, IEEE Computer Society, 2014

분류:소프트웨어 공학