[소프트웨어 공학 이론과 실제] 1. 소프트웨어 공학 개요
2025. 6. 30. 21:23ㆍSoftware Engineering/책 정리
https://www.yes24.com/product/goods/109994534
해당 책을 정리한 내용입니다.
학습목표
- 소프트웨어의 오류로 인하여 발생한 대표적인 사고 사례를 알아본다.
- 소프트웨어 개발에 어떠한 문제들이 존재하는지, 소프트웨어 개발이 왜 어려운지 알아본다.
- 소프트웨어 공학이란 무엇인지 그 의미를 명확히 이해한다.
1. 소프트웨어 고장 사례
소프트웨어 결함 사례
- 위성 : 단위 오류 누적으로 인한 위성 궤도 이탈
- 차 해킹 : 차량 해킹을 통한 제어
- 항공기 : 설계 오류로 인한 오류값 오작동 → 추락
- 테슬라 : 인식 오류 → 사망사고
- 위성 폭파 사고
- 차 급발진 사고
- 클라우드 불능 → 연계 서비스 사용 불가
- 테슬라 API 장애 → 잠금해제 불가
- 열차 지연
- 로봇팔 오작동 → 인명피해
2. 소프트웨어 위기
1. 소프트웨어 위기의 등장
- 소프트웨어 위기(Software Crisis)
- 컴퓨터에 의한 계산 용량과 문제의 복잡성이 급격히 증가함에 따라 발생한 충격
- 정확하고 이해할 수 있고 검증 가능한 컴퓨터 프로그램 작성의 어려움
- 소프트웨어가 처리해야 하는 문제의 복잡성, 사용자의 높은 기대, 빈번하게 발생하는 변화에 근거함
- 많은 프로젝트 들이 배포조차 되지 못함
2. 소프트웨어 위기의 원인과 증상
- 위기 원인 : 전반적 소프트웨어 프로세스의 복잡성 증가 + 전문 분야로서 상대적 미성숙함
- 개발 프로젝트 실패 원인
- 소프트웨어 규모의 대형화 및 복잡화에 따른 개발 비용 증대
- 하드웨어 기술의 급진전으로 인한 소프트웨어 개발 기술의 상대적 부진
- 하드웨어 비용 대비 소프트웨어 가격 상승 폭 증가
- 소프트웨어 유지보수의 어려움과 개발 정체 현상 발생
- 소프트웨어 개발 프로젝트 기간 및 소요 예산에 대한 정확한 예측의 어려움
- 신기술에 대한 교육 및 훈련의 부족
- 사용자의 소프트웨어에 대한 기대치 증가
- 소프트웨어에 대한 사용자 요구사항의 빈번한 변경 및 반영
- 소프트웨어의 어려움 증상
- 예산 초과
- 일정 지연
- 저품질 소프트웨어 개발
- 비효율적 소프트웨어 개발
- 사용자 요구사항 불만족
- 산출물 관리 어려움
- 증상 누적 시 개발 실패 or 사용자에게 전달되지 못함
- sw 공학적 기술 적용도 성공/실패를 명확히 결정하진 못함
- 여전히 통제 불가능, 예측 불가능한 문제 다수
3. 소프트웨어 개발이 어려운 이유
- sw 엔지니어의 지식과 경험에 따라 다른 결과물 산출(창의적 활동)
- sw 개발의 어려운 이유
- 의사소통 문제
- 다양한 역할 담당자들의 자신의 도메인에 따른 의미 해석 → 잦은 의사소통 오류 발생
- 다양한 경로의 의사소통 + 많은 의사소통 양 ⇒ sw 개발의 어려움 & 느린 진행속도
- 시스템의 순차 특성
- 개발(2차원 평면) ⇒ 실제 동작(3차원)
- 3차원 오류 발생을 방지한 2차원 평면에의 정리 필요
- 개발(2차원 평면) ⇒ 실제 동작(3차원)
- 개발에 의한 결과물
- sw는 개발활동의 결과물 ⇒ 개발자의 경험과 지식, 노하우의 중요성
- 오픈소스도 결국 개발 활동의 선행됨이 필요
- 프로젝트의 복잡한 특성
- 저마다 다른 특성의 프로젝트에 동일한 프로세스 적용의 어려움
- 프로젝트마다 다른 개발 기간
- 동일 기능에 있어서도 적용 기술에 따른 다른 개발 과정
- 개발자 인원 수 에 따른 다른 프로젝트 운영 방식
- 목적에 따라 다른 프로젝트 관리 방식
- 개발자의 특성
- 개발자의 특성에 따라 천차만별의 개발 난이도
- 다양한 관리 이슈
- 팀을 이루어 개발하는 것이 일반적
- 많은 세부 관리 활동 필요
- 고품질 sw를 개발해야하는 공통의 목표와 alignment 필요
- 팀을 이루어 개발하는 것이 일반적
- 의사소통 문제
4. 소프트웨어의 특성 정보
소프트웨어 개발 비용
- 소프트웨어 개발 시 비중 : 분석 및 설계(40%) > 코드 개발(20%)
- 테스트(40%)
소프트웨어 개발 및 유지 보수
- 운영 유지 비용이 개발비용의 약 2배
- 개발 시 운영 유지 비용 절감 방안 고려가 중요
소프트웨어 개발 시 오류의 근원
- 오류
- 문서화 및 기타 오류(35%) & 코드 작성 오류(30%) > 로직 설계 오류(20%) & 기능 오해(15%)
- 기능 오해, 로직 설계 오류 : 쉬운 발견과 수정
- 코드 잠재 오류, 문서화 불일치 : 개발 완료 시에도 어려운 수정
소프트웨어 고장 그래프
- Infant Morality : HW 개발 시 성능 조정 & 테스트로 오류 수정 → 오류 발생률 최저 감소 → 마모 or 낡음 → 성능 저하 → 고장 발생률 급증 → 성능 유지를 위한 주기적 교체 과정
- SW : 마모 없음 → 일정 사용 후 변경 과정(코드 수정 → 성능 개선) → 복잡한 코드 구조 → 어려운 이해
- 변경으로 인한 소프트웨어 구조가 없도록 코드 구조의 체계적 모듈화 & 융통성 있는 코드 작성
- 이를 위한 체계적 공학적 기법 적용 필요
- 변경으로 인한 소프트웨어 구조가 없도록 코드 구조의 체계적 모듈화 & 융통성 있는 코드 작성
5. 인공지능 시대의 소프트웨어 위기
- 4차 산업 혁명의 특징
- 초연결(Hyper-connected) : 객체간 상호 연결성의 확장(실시간 데이터 공유의 질적-양적 확대)
- 초융합(Hyper-Convergence) : 초연결 환경의 조성으로 이종 기술-산업 간 결합 촉진 → 새로운 융합 산업 출현
- 초지능(Hyper-Intelligence) : 서비스 활동의 질적 향상(최적 의사 결정을 통한 문제 해결) → 영역에서 더 나은 서비스를 제공하는 지적 역량
- 소프트웨어 시장 규모 확대와 지능화 속에서의 문제점 발생
지능 소프트웨어 개발의 남발
- 무분별한 학습 알고리즘이 응용 소프트웨어 개발에 적용 됨
- 기계 학습 알고리즘 적용 문제 : 적합한 알고리즘 인지, 어떤 입력을 구성하여 제공하는지, 최적해 결정을 위한 적합한 정책 적용 등 충분한 검토 부족
지능 소프트웨어 사고 위험
안전 중심 소프트웨어 개발에의 알고리즘 적용
적용 시 예상 가능 문제
증권&주식 예측 알고리즘 : 재산상 손실
자율 주행차 or 자동차 조립 공정 오류 : 재산 손실 & 인명 피해(폭스바겐사 사망 사고)
부족한 전문 지식 → 사고 원인
학습하지 못한 알고리즘 or 예측 불가 환경 ⇒ 시스템 출력이 사고의 원인이 될 수 있음
⇒ 안전 측면에서의 소프트웨어 품질 고려 필요
3. 소프트웨어 공학 기술의 적용
1. 소프트웨어 공학적 기법의 종류
- 다양한 공학적 기법의 목표 : sw 품질 향상 및 사용자에게의 신속한 sw 전달
- 기술 영역이나 도메인에 따라 보다 특화된 기법 및 기술 적용 가능
구조적 프로그래밍
- 쉬운 프로그램 이해 & 체계적 논리 표현을 위한 공학적 접근 방법
- Dijkstra의 프로그램 구성
- Sequence(순차), Repetition(반복), Selection(선택)의 구조로 구성
- 하위 수준에서의 구조적 프로그램 개발의 근간
- DeMarcro & Pages-Johnson
- 개발 이전 분석 및 설계 단계에서의 모듈화(Modularity)의 개념과 단계적 상세화(Stepwise Refinement) 개념 제시
- 설계에 대한 구조화 제안
객체지향 프로그래밍
- 구조적 프로그래밍의 패러다임에서 발전
- Simula-67 : 첫 객체지향 언어
- Smalltalk : 진정한 첫 객체지향 언어
- 특징
- 클래스 개념 기반의 캡슐화 및 정보 은닉, 상속, 다형성 등 개념 제공
- 소프트웨어를 직관적으로 이해하고 쉬운 유지보수 및 재사용성 시원
소프트웨어 컴포넌트 및 재사용
- 소프트웨어 재사용
- 기존의 코드 묶음을 Component로 명세 → 재사용 시도
- 장점
- 컴포넌트 재사용을 통한 개발시간 단축, 컴포넌트 조립을 통한 대규모 소프트웨어 개발 가능
- 소프트웨어 컴포넌트
- 재사용 가능한 코드
- 코드에 대한 명세 포함
- 빠른 개발
- 기존 검증 컴포넌트 사용 → 개발 소프트웨어 품질 향상
통합 개발 환경(IDE, Intergrated Deelopment Environment)
- 소스 코드 작성, 컴파일 및 디버깅, 크로스 컴파일, 배포 등 프로그램 개발에 관련된 일련의 작업을 하나의 프로그램 안에서 처리 하도록 지원하는 통합 소프트웨어 개발 환경
- 이전에는 별도 프로그램으로 제공
- 이러한 단위 프로그램들을 하나로 묶어 대화형 구성 & GUI 제공
소프트웨어 프로토타이핑
- 소프트웨어 개발 과정 리스크
- 사용자의 과도한 변경 요청
- 현상의 원인 : 소프트웨어는 눈에 보이지 않고, 만질 수 없는 결과물
- 잦은 변경 요청 → 빈번한 재작업 → 개발 시간 지연 or 품질 저하
- Prototyping 기법
- 개발과정 리스크를 줄이기 위한 접근 방법
- 개발 전 사용자가 원하는 소프트웨어 시스템의 원형(프로토타입) 개발
- 프로토타이핑 목적
- 최종 소프트웨어 개발 완료 전 사전에 보여줌 → 사용자 요구사항 명확한 반영 및 확장 목적
소프트웨어 개발 프로세스
- 폭포수 모델
- 가장 전통적, 가장 보편적 소프트웨어 개발 절차
- 요구사항, 분석, 설계, 코딩, 테스트, 배포 등 절차를 통한 소프트웨어 개발의 체계화
- 문제점
- 개발 프로젝트의 다양한 특성
- 잦은 요구사항 변경, 신속한 시장 대응 시간 요구, 장기간 개발에 따른 기술 변화
- 개발 프로젝트의 다양한 특성
- 새로운 개발 방식
- 점진적 개발, 프로토타입 개발, 나선형 개발, V 모델, 애자일 개발, DevOps 개발
소프트웨어 검사 및 검증
- 소프트웨어 결함 원인
- 요구 사항 오인
- 부적절한 설계 과정
- 코딩 오류 → 내재된 소프트웨어 결함 → 실사용 환경에서의 고장
- 고품질 소프트웨어 개발을 위한 검사 및 검증(Verification & Validation) 필요
- 검사 및 검증을 위한 공학적 기법
- ex) 소프트웨어 테스트
- 목적 : 체계적으로 설계 및 개발된 테스트케이스 이용 → 정확한 동작 확인 & 잠재 결함 발견 ⇒ 고장 발생 가능성 감소
- ex) 소프트웨어 테스트
소프트웨어 형상 관리(Configuration Management, 구성 관리 기술)
- 변경 발생 필수 불가결
- 변경이 발생하지 않도록 관리하는 것도 중요
- 발생한 변경을 어떻게 처리하고 관리할 것인지 중요
- 변경의 영향
- 변경이 어느 부분에서 어떻게 발생했는지 체계적 기록 및 관리 필요
- 이를 위한 공학적 접근 방법
- 형상 관리
- 소프트웨어의 변경 사항을 체계적으로 추적하고 통제하는 활동
- 하드웨어 형상 변경의 관리 기술을 소프트웨어 구성 요소에 적용
- 개발 산출물(소스 코드 포함) + 형상 항목(Configuration Item) 형태로 작업 산출물 정의 및 형상 항목 간 변경 사항 추적과 통제 정책 수립하여 관리하는 활동
소프트웨어 아키텍처
- 소프트웨어의 복잡성과 대형화로 인한 긴 개발 시간 ⇒ 긴 소프트웨어 수명
- 장기간 사용되는 소프트웨어들은 운영 환경 및 정책 변화를 통해 지속적 수정 및 보완
- 이 과정을 통해 비구조화 및 로직 이해의 어려움 증가
- 소프트웨어 설계 구조에서의 변화를 반영한 소프트웨어 아키텍처 필요
- 장기간 사용되는 소프트웨어들은 운영 환경 및 정책 변화를 통해 지속적 수정 및 보완
- 소프트웨어 아키텍쳐
- 소프트웨어에서 상호 독립성 높은 구성 요소들을 식별하고 이들 간의 관계를 정의한 설계 산출물
- 변경에 강한 아키텍처 설계
- 사용자 인터페이스, 처리 로직, 데이터 관리 등 분리를 통한 구조 설계 및 설계 패턴 적용 ⇒ 융통성 있는 아키텍처 개발
2. 소프트웨어 공학의 정의와 원리
소프트웨어 공학의 정의
- 소프트웨어 공학 기술 : 전체 수명주기 지원 & 사용자 요구사항 충족을 위한 활동
- 소프트웨어 공학의 목표 : 이를 통한 보다 좋은 품질의 소프트웨어 개발
소프트웨어 공학의 원리
엄격성(Rigor)과 정형성(Formality)
- 소프트웨어 개발이 창의성과 독창성을 요하는 활동이라는 점을 고려한 것
- 방만함이나 지나친 자유스러움을 제안하기 위한 보완적 수단
- 정확한 소프트웨어 개발을 위한 필수 요소
- 정형성
- 수학적 이론을 근간으로 하기 때문에 누구나 동일한 의미로 해석할 수 있어야 함
- 엄격성의 대표 원리
- 엄격성 적용
- 프로젝트 관리 및 스케줄 관리
- 문서화 요구 시
관심사의 분할(Separation of concerns)
- 소프트웨어는 복잡하며 다차원적 요소 고려 필수
- 관심사의 분할 : 복잡함 해결을 위해 적용되는 원리
- 예시
- 처리 로직과 데이터 관리를 별도로 고려
- 소프트웨어 개발 과정 : 요구사항 분석, 설계, 구현, 테스트 등으로 구분
- 복잡한 문제 → 단순하게 고려
모듈화(Modularity)
- 모듈 : 독립적 기능을 수행하는, 작은 단위의 구별되는 프로그램 조각
- 모듈화 원리 적용 → 소프트웨어를 쉽게 분리 or 조립 → 소프트웨어 기능에 대한 이해도 향상
- 모듈화 : 소프트웨어 구성 작은 단위 모듈 간 관계를 통해 설명
- 결합력(Coupling) : 모듈간 관련성 정도
- 응집력(Cohesion) : 모듈 내 속성 간 관련성
추상화(Abstraction)
- 세부사항들을 감추고 대상물의 특징으로 사물을 대표하도록 정의하는 원리
- 관심사를 잘 표현할 수 있는 원리
- 추상화 원리 적용 대표 소프트웨어 구성 요소 : 함수 정의, 매크로 함수, 객체, 추상 데이터 타입, 반복문 등
변경의 예측(Anticipation of changes)
- 변경 : 필수 불가결 ⇒ 변경에 잘 대처하는 방법 필요
- 변경 예측 부분 : 모듈화 구조를 통한 분리
- 독립된 모듈 정의 ⇒ 추후 변경 발생 시 해당 모듈만 수정해 변경 영향 최소화
일반화(Generality)
- 소프트웨어의 기능을 다양한 플랫폼이나 환경에서 사용할 수 있도록 최대한 정형화하고 공동 활용성을 높이고자 하는 원리
- 일반화 상승 시 개발 시간 지연 or 해당 기능 수행 속도 저하 초래 가능성
- 불특정 다수에게 서비스를 제공하는 소프트웨어(e.g. application server)에는 일반화 원리 적용 필수
점진성(Incrementality)
- 소프트웨어를 단계적이며 순차적으로 개발하는 원리
- ex)
- 기능 순차 개발
- 테스트 점진적 수행
- 점진적 개발 & 사용자 배포 → 피드백 → 수용
명세화(Documentation)
- 개발 과정 시 생성되는 정보의 체계적 기술
- 팀 작업에서 중요
- 지속적으로 진화하는 소프트웨어에서, 유지보수를 위한 중요한 활동
- 오픈소스에도 활용성 증대 방안(코드 기능, 인터페이스 등)