1장 소프트웨어 공학 개요
소프트웨어의 종류
- 주문형, 패키지형, 임베디드 시스템
- 실시간 소프트웨어, 자료처리 소프트웨어
소프트웨어 공학의 정의
- IEEE : 소프트웨어의 개발, 운용, 유지보수 및 파기에 대한 체계적인 접근
- W.Humphrey : 질 좋은 소프트웨어를 경제적으로 생산하기 위하여 공학, 과학, 수학적 원리에 의하여 소프트웨어를 개발해야한다
소프트웨어 품질 (효-용-신-유-재-)
- 효율성(efficiency)
- 사용용이성(usability)
- 신뢰성(reliability)
- 유지보수성(maintainability)
- 재사용성(reusability)
소프트웨어 프로젝트 작업
- 요구분석과 명세화
- 도메인 분석, 문제 정의, 요구 추출, 요구 분석, 요구 명세화
- 설계 : 가용한 기술로 어떻게 구현되어야하는지 기술
- 시스템 엔지니어링, 소프트웨어 아키텍쳐
- UI 설계, DB 설계
- 모델링 : 도메인이나 소프트웨어의 표현을 만들어 나가는 과정
- 유스케이스 모델링
- 정적 모델링, 동적 모델링, 행위 모델링
- 프로그래밍
- 품질보증
- 리뷰, 인스펙션, 테스트
- 배포
- 프로세스 관리
2장 소프트웨어 프로세스
폭포수 모델 (Waterfall Model)
- 각 단계가 다음 시작 전에 끝나야 함 -> 느림
- 프로토타입과 재사용의 기회가 줄어듦
프로토타입 모델 (Prototyping Model)
- 인간-기계 상호작용 프로토타입
- 프로토타입을 만든다 - 프로토타입을 평가한다
점증적 모델 (Incremental Model)
- 점증적 방법: 기능별로 릴리즈
- 반복적 방법: 릴리즈 할때마다 기능의 완성도를 높인다
- 기능이 부족하더라도 빨리 릴리즈 가능
나선형 모델 (Spiral Model)
- 진화 단계
- 계획 수립
- 위험 분석
- 개발
- 평가
- 반복적인 개발 및 테스트 -> 강인성 향상
- 관리, 위험 분석이 중요
진화적 모델 (Evolutionary Model)
- 초기에 요구사항을 파악하기 힘들고 구현이 어려운 경우, 요구사항 분석을 한 번이상 반복
- UP (Unified Process)
- 도입 단계 : 프로젝트의 범위를 설정, 목표를 명확히
- 정련 단계 : 요구를 찾아내어 설계를 완성
- 구축 단계 : 제조 단계, 요구의 테스트 마무리
- 전환 단계 : 릴리즈
애자일 프로세스 (Agile Process)
- 특징
- 짧은 릴리즈와 반복
- 점증적 설계
- 사용자 참여
- 문서 최소화
- 비공식적 커뮤니케이션
- 요구와 환경의 변화를 가정
익스트림 프로그래밍 (eXtreme Pragramming)
- 애자일 방법론 중 하나
- Planning : 요구사항을 작은 요소로 분할
- Analysis
- Design
- Execution : Coding, Testing
- Wrapping : small release, process improvement
- Closure : launch
스크럼 (Scrum)
-
조직적으로 애자일 방법론을 적용
-
구성 요소
- 백로그 (Backlog) : 할 일 목록
- 스프린트 (Sprint) : Iteration을 의미, 1~4주의 기간
- 스크럼 회의 : 매일 15분간 진도 확인 회의
- 리뷰 : 스프린트 종료 후 구현된 산출물을 리뷰
- 스프린트 회고 : 방법론 자체에 대한 리뷰 수행
프로세스 모델 선정
- 일반적인 구축 : 폭포수 모델
- 대규모 재구축 : 점증적 모델, 나선형 모델
- 임베디드 시스템 : 점증적 모델
- 프로젝트 타당성 검토 : 프로토타입 모델, 나선형 모델
- 연구형 개발 : 프로토타입 모델, 나선형 모델
- 소규모 : 애자일 프로세스
프로세스 활동
-
Software speicification
- Feasibility study(타당성 조사)
- Requirements elicitation and analysis(요구사항 도출 및 분석)
- Requirements specification(요구사항 명세)
- Requirements validation(요구사항 검증)
-
Software deisgn and implementation
- Architectureal design
- Interface design
- Component design
- Data structure design
- Algorithm design
-
Software validation
- Vertification and validation (V&V) : 시스템이 요구사항을 충족한다는 것을 보여주기 위한 활동
- Component or unit testing
- System testing
- Acceptance testing
- Vertification and validation (V&V) : 시스템이 요구사항을 충족한다는 것을 보여주기 위한 활동
-
Software evolution
- 변화하는 비즈니스 환경에 따라 요구사항이 변화함에 따라 소프트웨어 진화하고 변화해야 한다
3장 프로젝트 관리
프로젝트 관리 활동
- 제안서 작성
- 프로젝트 계획 및 스케줄링
- 프로젝트 비용 계획
- 프로젝트 모니터링 및 검토
- 인력 선발 및 평가
- 보고서 작성 및 프레젠테이션
프로젝트 개발 노력 추정
- 프로젝트 요소
- 문제의 복잡도, 시스템의 크기, 시스템 신뢰도
- 자원 요소
- 인적 자원, H/W 자원, S/W 자원
- 생산성 요소
- 개발자 능력, 개발 방법론
기능 점수 모델 (UFP: Unadjusted Function Point) 산정
- 5가지 소프트웨어 구성 요소별 기능 점수 가중치 부여
- 외부 입력, 외부 출력, 외부 질의
- 내부 논리 파일, 외부 인터페이스 파일
기능 점수 모델 (VAF: Value Adjustment Factor) 산정
- 14가지 기술적 분야에 대한 복잡도를 고려하여 0~5 점수 부여
기능 점수 모델 (AFP: Adjusted Function Point) 산정
- AFP = UFP * VAF
객체 점수 모델
- Cc(Class Complexity): 클래스의 개수 추정
- Wi: 사용자 입력의 종류 분류, 가중치 부여
- 최종 클래스 개수(TCc) = Cc(Wi+1)
- Effort = TCc X MD(클래스 1개 개발하는데 소요되는 생산성 추정 값)
프로젝트 일정 관리
- Action: 프로젝트에서의 활동
- Milestones(이정표): 프로젝트에서의 중요한 시점
- Deliverables(납품물)
PERT/CPM 차트
- 임계 경로
Pert Chart에서 소요 기간이 가장 긴 경로
-> 프로젝트 완료까지 필요한 최소 시간
간트(Gantt) 차트
- 가로축: 시간
- 세로축: 작업
- 마일스톤: 마름모 표시
- 파란색 막대: 여유시간
애자일 일정 계획
- 스토리카드 단위의 일정 계획
프로젝트 인적 자원 관리
계층형 팀
- 초보자와 경험자를 분리
- 장점 : 소프트웨어가 크고 구조가 계층적으로 잘 나누어진 경우에 적합
- 단점 : 기술 인력이 관리, 의사 전달 경로가 김
Egoless 팀
- 민주주의 방식, 구성원이 동등한 책임과 권환
- 장점 : 의사 교류 활발, 복잡한 장기 프로젝트에 적합
- 단점 : 책임이 불명확, 느린 의사결정, 대규모 프로젝트에 부적합
책임 프로그래머 팀의 구성
- 작은 팀으로 구성, 책임 프로그래머가 통제
- 책임 프로그래머, 프로그램 사서, 보조 프로그래머, 프로그래머로 구성
- 장점 : 의사 결정이 빠름, 소규모 프로젝트에 적합
- 단점 : 한 사람의 능력과 경험이 프로젝트의 성패 좌우
프로젝트 위험 관리
- 위험 종류
- 프로젝트 위험, 제품 위험, 비즈니스 위험
- 위험 관리 프로젝트
- 위험 식별
- 위험 분석
- 위험 대처 계획 수립
- 위험 모니터링
위험 대처 계획 수립
- 회피 전략: 위험이 발생할 확률을 줄임
- 최소화 전략: 위험의 영향을 줄임
- 비상 계획: 위험이 발생할 경우 대처 방법
4장 요구사항 개발 및 정의
요구사항 분석과정
- 도메인 분석 -> 요구사항 추출 -> 분석 및 명세화 -> 검토
도메인 분석
소프트웨어 엔지니어가 문제를 더 잘 이해하기 위하여 도메인에 대하여 알아가는 과정
- 도메인: 소프트웨어를 사용할 것으로 예상되는 고객이 일하는 분야의 비즈니스나 기술
- 도매인 분석의 이점
- 빠른 개발, 더 좋은 시스템 구축 가능, 확장 예견
문제 정의와 범위 설정
- 문제 정의서
- 문제 정의 범위
- 시스템에 포함되어야 할 기능 결정
요구사항 추출
- 요구사항 추출 방법
- 관찰, 인터뷰, 브레인스토밍, 프로토타이핑, 유스케이스 분석
관찰
- 사용자를 관찰, 시간이 많이 소요된다
인터뷰
- 문제에 대해 최소한의 허용 가능한 솔루션이 무엇인지 질문
- 다이어그램 작성을 요구
브레인스토밍
- 관련자 모두가 참여
- JAD(Joint Application Development)
- 최종 사용자와 개발자가 시스템 개발 논의
프로토타이핑
- paper prototype: 가장 단순한 형태
- mock-up of the UI : 가장 흔한 형태
요구사항 문서 구성
- 환경 및 시스템 모델
- 기능적 요구사항
- 비기능적 요구사항 : 성능, 효율 등
5장 유스케이스 모델링
유스케이스
시스템이 actor에게 관찰 가능한 가치의 결과를 생산하기 위해 수행하는 일련의 행동 및 그 변형들의 집합
- 유스케이스는 완전한 기능을 명세한다
- 시나리오 : 특정한 목표를 달성하기 위해 수행되는 일련의 행동이나 집합
유스케이스 다이어그램
- 시스템, 액터, 유스케이스를 포함
- 시스템 : 개발될 시스템의 경계
- 액터 : 시스템과 상호작용할 때 외부 에이전트가 수행하는 역할
- 유스케이스
- 항상 액터에 의해 개시됨
- 액터에게 가치를 제공
- 완전한 설명이어야 함
유스케이스 간의 관계
- 포함 관계
- 다수의 유스케이스가 공통된 행동을 수행하는 경우, 포함시킬 수 있다.
- 확장 관계
- 한 유스케이스의 확장 지점에 액션을 추가하여 다른 유스케이스로 확장
유스케이스 검증
- 검증: 구현을 테스트
- 확인: 사용자의 요구를 충족시키는가?
- 워크쓰루: 액터와 시스템의 역할극
유스케이스 실현
- 유스케이스는 collaboration으로 실현
6장 클래스 모델링
UML
-
Unified Modeling Language
-
객체지향 소프트웨어를 모델링하기 위한 표준 그래픽 언어
-
클래스
- 사각형으로 표현
- 이름, 속성, 오퍼레이션 표시
-
속성
-
오퍼레이션
- getter(), setter()
- operation signature의 표현
1+ digit(n:int)
-
가시성
- public(+), private(-), protected(#)
-
연관관계
- 관계이름: 동사, 동사구
- 다중성: 관계 사이에 개입하는 인스턴스 개수
- 0..1: 선택적 관계
- 1..*: 1개 또는 그 이상
- 3..5: 3개에서 5개까지
- One-to-one
- Many-to-many
- One-to-many
- 역할 이름: 역할, 링크 양 옆에 표시
- 방향성 : 연관관계는 기본적으로 양방향성, 단방향으로 제한 가능
-
전체/부분 관계 (Aggregation)
- 전체 객체가 부분 객체를 포함
- 흰색 다이아몬드로 표시
- Composition 관계
- aggregation이 강한 관계
- 전체가 소멸되면 부품도 소멸됨
- 검은 다이아몬드로 표시
- 일반화 관계 (Generalization)
- 일반화: 두 가지 이상의 클래스의 공통 요소를 일반화
- 상세화(specialization): 수퍼클래스를 서브클래스로 구체화
- 추상클래스
- (abstract)로 표시
- 추상 오퍼레이션: 구현이 없는 오퍼레이션
- 인터페이스
- <<interface>>로 표시
- Notes = 주석
OCL (Object Constraint Language)
- 소프트웨어의 모듈의 제약사항을 정형적으로 나타내도록 설계된 명세 영어
7장 동적 모델링
동적 모델링
시스템의 기능을 만족시키기 위해 각 빌딩 블록이 어떻게 상호작용하는지를 표현
- 표현방법 : 시퀀스 다이어그램, 상태 다이어그램, 활동 다이어그램
시퀀스 다이어그램
시스템의 동적인 측면을 모델링하기 위해 사용
- 객체, 액터, 메시지(액터 -> 객체)로 구성
- 수직 축은 시간 흐름
- 액터를 왼쪽에 표시
- 객체마다 life line을 그림
- activation box : 객체의 활성화를 표현
- 메시지는 activation box 사이에 화살표로 표시
- 객체가 소멸된 이후에는 라이프라인이 중지되며 ‘X’로 표시
- opt(if), alt(switch), loop(for)
상태 다이어그램
시스템 전체, 시스템의 일부, 개별 객체에 대한 동작을 기술하기 위한 목적
- 상태 다이어그램이 내부에 내장 가능
- 이때, 내부 다이어그램의 상태를 substate(서브상태)라고 함
상태
주어진 시점에 시스템은 어떤 상태에 있음
- 표현
- 상태 : 둥근 사각형 안에 상태 이름을 표시하여 나타냄
- 시작 상태 : 검은 원
- 종료 상태 : 원 안에 원
트랜지션
이벤트 발생으로 인한 상태 변화 (즉시 일어남이 원칙)
- 트랜지션 위에는 상태 변화를 일으키는 이벤트를 표시
- 표현 : 화살표로 표시
- 종류 : 경과 시간 표시 트랜지션, 조건 표시 트랜지션
액티비티
시스템이 어떤 상태에 있을 때 수행하는 행위
- 인터럽트 가능
- 표현 : 상태 내부에 사각형 박스로 표시
액션
시간 경과 없이 즉시 일어날 수 있는 동작
- 표현 : Enter/action, Exit/action, event/action
액티비티 다이어그램
객체나 컴포넌트가 수행하는 작업의 흐름을 이해, 유스케이스 사이의 관계와 상호작용을 표현하기 위해 사용
-
상태 다이어그램과 유사
-
병행 액티비티를 표현할 수 있다
-
표현
- activity : 모서리가 둥근 사각형
- transition(가드 컨디션, 전송-절, 액션표현) : 화살표
- decision point : 다이아몬드
병행 처리 표현
- Fork
- 단일 입력 트랜지션과 다수 출력 트랜지션
- Rendezvous
- 다수 입력 트랜지션과 다수 출력 트랜지션
- Join
- 다수 입력 트랜지션과 단일 출력 트랜지션
Swimlane
- 같은 swimlane에 있는 액티비티들은 동일한 클래스와 관련된 것
동적 다이어그램의 구현
아키텍처 설계
설계 원리 2 : 응집력을 높이기
- 응집력 향상 (응집력이 높은 순)
- 기능적 응집도 : 특정 결과를 계산하기 위한 코드만 존재
- 이해하기 쉬움, 재사용성 높음, 대체 가능성 높음 -> 유지보수성 높음
- 계층적 응집도 : 연관 기능 같은 계층
- 예) Application(상), DB system(하)
- 순차적 응집도 : 이전 프로시저 출력 -> 다음 프로시저의 입력
- 교환적 응집도 : 동일한 입력을 사용하는 프로시저들의 집합
- 절차적 응집도 : 차례로 수행되는 프로시저를 모음
- 시간적 응집도 : 같은 시점에 수행될 연산을 모음
- 실용적 응집도 : 다른 응집 단위에 배치할 수 없는 프로시저들의 집합
설계 원리 3 : 결합력을 낮추기
- 내용 결합 : 타 컴포넌트의 내부 데이터를 비밀리에 수정
- 방지책 : 캡슐화
- 공통 결합 : 전역 변수 사용 시 항상 발생
- 제어 결합 : 플래그, 커맨드 이용 -> 타 프로시저 호출하여 제어
- 방지책 : operation의 다형성 사용, look-up table 사용
- 스탬프 결합 : 타 클래스를 매개변수로 사용
- 자료 결합 : 매개변수가 기본 자료형 또는 단순 라이브러리 클래스
- 루틴 호출 집합 : 하나의 루틴(메소드)가 다른 루틴 호출
- 타입 사용 결합 : 타 모듈에서 정의한 자료형 사용
- 포함 결합 : import & include
- 외부 결합 : 운영체제, 공유 라이브러리, 하드웨어 의존
- 방지책 : 의존성 코드 줄이기, facade 설계 패턴 사용
아키텍처 패턴
- 계층구조 스타일 : 각 서브시스템이 하나의 계층이 되어 하위층이 제공하는 서비스를 사용
- 클라이언트-서버 스타일
- 브로커 스타일 : 여러 노드에 소프트웨어 시스템을 투명하게 분산
- 트랜잭션 처리 스타일 : 연속적인 입력을 하나씩 읽어 트랜잭션으로 명시
- 트랜잭션 : 시스템에 저장된 데이터에 변경을 가하는 명령들의 집합
- 파이프 필터 스타일 : 비교적 단순한 형태의 데이터 스트림이 프로세스에 차례로 전달되어 처리되는 구조
- MVC 스타일 : Model, View, Controller로 구성
클래스 설계 원칙
- 단일 책임의 원칙 (SRP: Single Responsibility Principle)
- 클래스는 한가지 종류의 책임만 가져야 한다
- 객체는 약한 결합력, 강한 응집력을 실현
- 개방-폐쇄의 원칙 (OCP: Open-Closed Principle)
- 확장에 대해서는 open, 변경에 대해서는 close
- 모듈을 자체를 변경하지 않고도 그 모듈을 둘러싼 환경을 바꿀 수 있어야 한다
- 인터페이스 분리의 원칙 (ISP: Interface Segregation Principle)
- 클라이언트는 자신이 사용하지 않는 메소드와 의존 관계를 갖지 않아야 한다
- 리스코프 교체원칙 (LSP: Liskov Substitution Principle)
- 자식 타입은 언제나 부모 타입을 대체할 수 있어야 함
- 의존 관계 역전의 원칙 (DIP: Dependency Inversion Principle)
- 클라이언트는 구체적 클래스가 아닌 인터페이스나 추상 클래스에 의존해야 한다
9장 디자인 패턴
생성 패턴
Factory pattern
- 객체 생성을 위해 인터페이스를 정의
- 자식 객체 중 어떤 것이 필요한지 실행 시간까지 알 수 없을때 사용
Abstract Factory pattern
- 구체적인 클래스를 명시하지 않고 그 객체와 연관되는 객체 그룹을 생성하는 인터페이스 제공
Prototype pattern
- 객체를 사용할 때 다시 생성하지 않고 복사해서 사용
- 클론 메소드 : 객체를 복사하는 메소드
구조 패턴
Composite pattern
- 객체의 트리를 나타내는데 사용
- 기본 클래스와 이를 포함하는 컨테이너 클래스를 재귀적인 형태로 표현
Decorator pattern
- 런타임에 객체의 기능을 추가하기 위해 사용
- 객체 생성 없이 개별 객체에 데코레이터를 이용하여 동작을 첨부 가능
Adapter pattern
- 애플리케이션의 기능을 외부에서 필요한 형태로 수정하여 사용하기 위해 사용
- 원하는 인터페이스를 추상 클래스로 정의
Facade pattern
- 시스템을 구성하는 많은 기능의 간단한 입구 역할 제공
- 사용하려는 클래스 중 특정 클래스를 인터페이스로 정의
Proxy pattern
- 복잡하거나 생성이 오래걸리는 객체를 좀 더 간단한 객체로 표현
- 특정 객체에 접근을 조절하기 위하여 대리자를 세움
행위 패턴
Observer pattern
- 정보 제공자와 이용자 사이의 연관을 관리하는 패턴
- 단일 객체가 영향 받는 객체 집합에 대하여 같은 이름의 메소드를 호출
Mediator pattern
- 관련된 객체 사이에 레퍼런스를 피하고자 할 경우 사용
- 여러 객체가 서로 메시지를 주고 받는 행위를 특정 객체 안에 캡슐화
책임 체인 pattern
- 사용자가 작업을 어떤 객체에게 맡길지 모를때 사용
- 작업을 수행하는 객체를 체인처럼 엮어 놓았다가 외부의 요청이 있으면 체인에 넘김
Command pattern
- 처리를 담당할 객체를 처리 박스에 요청하여 처리하는 패턴
- 커맨드 클래스 안에 명령을 캡슐화하여 넣음
State pattern
- 객체의 상태에 따라 구체적인 행위가 달라지는 경우에 적용
- 상태를 객체로 만들고 상태 클래스 안에 정적 변수로 저장
소프트웨어 테스트
- Test Driver : 간단히 구동하도록 작성된 프로그램
- Test Stub : 테스트 대상 컴포넌트에 의해 호출되는 컴포넌트를 시뮬레이션 한것
- IUT (Implementation Under Test)
Black Box 테스트 기법
- 주어진 명세로부터 테스트 케이스 유도
동등 분할
- 동치 클래스 결정
- 입력 값 영역 또는 출력 값 영역을 독립적인 집합으로 나눔
- 테스트 케이스 선정
- 집합의 원소 중 대표값 하나를 선택
- 동등 분할 클래스
- 유효한 입력 데이터와 유효하지 않은 입력 데이터를 구분
- 예) 식료품의 무게는 0부터 5000 사이의 값을 갖는 숫자이다
- Black Box 테스트 기법
경계 값 분석
- 동등분할의 경계부분에 해당하는 경계 값을 테스트 케이스로 선택하는 기법
- 유효 경계 값, 비유효 경계 값을 선택
- 결함 발견 율이 높고, 적용하기 쉽다
White Box 테스트 기법
- 소프트웨어나 시스템의 코드와 구조를 중심으로 테스트
- 컴포넌트 레벨의 구조는 구문, 결정, 분기문 등 코드 그 자체
- Coverage : 시스템 또는 소프트웨어의 구조가 Test suite에 의해 테스트 되는 정도
구문 테스팅과 커버러지
- 테스트케이스에 의해 실행된 구문이 몇 퍼센트인지 측정하는 것
- 제어 흐름 그래프 생성 (순차 구조, 선택 구조, 반복 구조) $$ coverage = \frac{covered\ stmt}{(total\ stmt - unreachable\ stmt)} $$
결정 테스팅과 커버리지
- 실행된 결정 포인트의 outcome이 몇 퍼센트인지 측정하고 평가
- “참"과 “거짓"의 모든 값을 가지면 100% 커버한다고 판다
조건 테스팅과 커버리지
- 결정 포인트 내에 있는 각각의 개별조건식이 “참"과 “거짓"의 모든 값을 가지는지 테스트
- 개별 조건식이 참 거짓을 가진다고해서 전체 조건식이 항상 참 거짓을 가지는 것은 아님
다중 조건 커버리지
- 결정 포인트 내에 있는 모든 개별 조건식의 모든 가능한 논리적인 조합을 고려하여 테스트
- 입력 조건이 2개이면 TF, FT, FF, TT 4개의 테스트 케이스 필요
테스트 종류
단위 테스트 (Unit Test)
- 프로그램의 기본 단위인 모듈에 대한 테스트
- 주로 화이트 박스 테스트를 이용
통합 테스트 (Integration Test)
- 모듈 통합 과정에서 수행하는 테스트
- 통합 과정에서 발생할 수 있는 오류를 확인
시스템 테스트 (System Test)
- 기능 테스트, 비기능 테스트
인수 테스트 (Acceptance Test)
- 요구대로 잘 작동하는지 고객과 함께 확인하는 테스트
대형 시스템 테스트 전략
- 빅뱅 테스트 : 전체 시스템을 하나의 단위로 테스트
- 점진적 테스트 : 시스템을 단계적으로 테스트
- 하향식 테스트
- 상향식 테스트
- 샌드위치 테스트