C09 모듈화 설계1. 모듈화 설계 개요2. 결합력(Coupling)의 이해3. 응집력(Cohesion)의 예시4. 모듈화 응용 기술C10 설계 패턴1. 설계 패턴 개요2. 생성 패턴3. 구조 패턴4. 행위 패턴C11 객체지향 설계1. 설계 원리2. 패키지 다이어그램패키지 다이어그램 생성계층화된 아키텍처 생성3. 자료 구조 설계4. 사용자 인터페이스 설계인터페이스 설계 절차인터페이스 클래스 설계5. 물리 구조 설계배치 다이어그램 작성기술 환경 명세C12 인스펙션1. 인스펙션의 중요성인스펙션의 정의인스펙션의 목적인스펙션 효과2. 인스펙션 참여자3. 인스펙션 절차1. 계획 활동2. 오버뷰 활동3. 준비 활동4. 인스펙션 미팅 활동5. 제3의 시간 활동6. 재작업 활동7. 후속 활동8. 인스펙션에 대한 평가4. 소프트웨어 리뷰 활동
C09 모듈화 설계
1. 모듈화 설계 개요
- 모듈화가 SW 개발의 근본 원리인 이유
- 이해가 쉬워짐, 팀 단위의 개발이 쉬워짐, 변경이 쉬워짐, 재사용 가능성 업, 추적성이 높아짐
- 좋은 SW 설계 시의 특성
- 계층적인 구조: 시스템은 서브시스템으로 구성, 서브시스템도 하위 기능 영역으로 구성, 기능 영역은 모듈로 구성
- 설계 결과가 독립적인 컴포넌트 - 모듈로 구성되어야 함
- 데이터와 처리 절차가 구분: 사용자 인터페이스 계층, 처리 계층, 데이터 계층
- 설계 결과가 독립적인 기능 단위로 구현
2. 결합력(Coupling)의 이해
- 좋은 설계 → 결합력을 최소화 → 모듈이 독립적인 기능을 갖기, 중복을 제거, 모듈간 상호작용 줄이기
다음은 결합력을 좋음 → 나쁨 순으로 정리한 내용이다
- 메시지 결합력(Message Coupling)
- 가장 결합이 느슨한 유형
- 객체지향 기준으로 객체가 캡슐화되어 다른 객체가 다른 모듈로 간주됨, 상호작용은 메시지 전달로만 이루어짐
- 메시지 전달? → di/ioc 처럼 쓰는 경우가 메시지 결합도 ㅇㅇ…
- react node에서 observable한 패턴 → 변수 변경시에 publish 하는 등
- annotation을 예로 → @PostConstruct 의 장점 → 별개의 함수/클래스가 생성되고 나서 메시지만 전달 받아서 처리할 수 있어서 결합력이 낮다 → 갈아끼우기 쉽다
- 데이터 결합력(Data Coupling)
- 2개의 모듈이 기본 데이터 타입(정수형, 문자형등) 변수에 의해서 상호작용 될 경우
- 일반적으로 함수는 서로를 호출(상호작용)하기에 피하기 어렵다
- 팁) 함수 호출시에 매게변수가 많으면(인터페이스가 넓으면) 좋지 않다 → 이때 매게변수를 구조화하면 좋다
- f(int a, int b, char c, int d, int e) → f(Customer c)
- 스탬프 결합력(Stamp Coupling)
- 두 모듈이 구조체와 같은 복합 데이터를 이용하여 상호작용 할 경우
- 꼭 구조체는 아니고 스탬프로 찍어서 보내주면 된다고 이해하면 된다. dto 라던가, 클래스라던가
- 질문: 매게변수를 구조화하면 코드의 이해도는 높아지지는 반면 결합력 단계가 낮아져 결합력은 떨어지는 것인가?
- 구조체 정의시에 관련있는 데이터끼리 묶어야 한다 → 아니면 구조체를 직관적으로 이해하기 어려워짐
- 팁) 굳이 정보 하나만 사용하는데, 정보가 포함된 구조체 전체를 넘길 필요는 없다
validatePhoneNumber(Customer c) → validatePhoneNumber(int phoneNumber)
- 제어 결합력(Control Coupling)
- 모듈간 매게변수 전달시에 매게변수가 함수의 내부 행위를 제어할 때
- 예) 변수 flag 값에 따라 함수의 내부 행위가 바뀔 때
- 그럼 flag에 대해 의존성이 생기고, 외부에서 flag 변경시에 호출받는 함수도 크게 영향 받음
- 외부 결합력(External Coupling)
- 2개의 모듈이 외부에 존재하는 다른 정보를 공유하고 있을 때
- 외부 정보: 파일, 디바이스 인터페이스, 프로토콜등이
- 데드락이 발생할 수 있음
- 공유 결합력(Common Coupling)
- 2개의 모듈이 광역 변수를 공유하고 있을 때
- 메모리 사용을 줄이고 프로그램을 간단하게 작성할 수 있으나, 모듈간 의존성이 높아짐
- 광역 변수를 추적하고 이해하기 어려워짐
- 내용 결합력(Content Coupling)
- 한 모듈에서 다른 모듈의 내부를 직접 참조할 때
- 현재는 거의 발생하지 않음
- 예시) 절차지향 언어에서 goto
뒤에 것이 바뀌었을 때 앞의 것이 바뀔 필요가 없는 정도로, 제어 결합력 정도로 끝내는 것이 좋다.
3. 응집력(Cohesion)의 예시
- 좋은 설계 → 응집력을 최대화 → 모듈이 독립적인 기능을 가짐
다음은 응집력을 좋음 → 나쁨 순으로 정리한 내용이다(~교환 응집력 까지는 유지보수하기 좋다)
- 기능 응집력(Functional Cohesion)
- 모듈을 구성하는 모든 요소가 하나의 기능을 구현하기 위해 구성된 경우
- 예시) 수학의 cos값 계산, 문장의 알파벳 오류 체크, 트랜잭션 기록을 읽기
- 순차 응집력(Sequential Cohesion)
- 모듈을 구성되는 문장 관계에서 한 문장의 실행결과가 다음 문장의 입력으로 사용되는 경우
- 이때, 마지막 문장이 기능 응집력을 충족해야 응집력의 효과가 향상된다
- 교환 응집력(Communicational Cohesion)
- 모듈을 구성하는 모든 요소가 동일한 입력/출력을 사용할 때
- 예시) 학생 ID를 입력받아 상세 정보를 가져와 GPA를 계산하고 주소 라벨을 출력하는 모듈이 있을 때, GPA 계산과 출력은 다른 기능이나 같은 입력을 사용하기에 모듈로 묶여 있다
- 절차 응집력(Procedural Cohesion)
- 모듈을 구성하는 문장들이 의미상 관련이 없지만 제어 흐름의 순서는 있을 때
- 즉 한 기능을 수행하기 보다는 실행 순서와 관련있게 구성 되어 있는 것
- 시간 응집력(Temporal Cohesion)
- 모듈을 구성하는 문장들이 SW 실행의 시간과 관련있는 것으로만 구성될 경우
- 예시) 데이터를 사용하기 전에 모든 변수를 처음에 초기화, 파일 사용전에 모든 파일을 오픈, 사용자에게 알림을 제공하기 위한 모든 데이터를 처리
- 이 경우에 필요없는 파일을 미리 열어놓거나 쓸대 없이 파일 포인터를 여러 개 사용하는 경우가 발생할 수 있음
- 논리 응집력(Logical Cohesion)
- 모듈을 구성하는 모든 요소가 같은 유형의 외부 동작들로 구성되는 경우
- 다수의 유사한 행위를 포함하며, 주로 flag 변수에 의해 실행 여부가 결정됨
- 이는 주로 유사한 행위를 따로 생성하지 않고 하나의 코드로 공유하려는 시도에서 발생
- 우연 응집력(Coincidental Cohesion)
- 가장 나쁜 형태의 응집력, 절대 작성 금지
- 모듈을 구성하는 모든 요소가 관련성이 없는 것으로 묶인 경우
4. 모듈화 응용 기술
- 모듈화와 소모 전력: 모듈화 → 소모 전력 다운
- 모듈화와 기술 부채: 모듈화 → 기술 부채 다운
C10 설계 패턴
1. 설계 패턴 개요
- 설계 패턴: 반복적으로 발생하는 문제에 대해 적합한 디자인 솔루션을 정의한 것
- GoF 설계 패턴이 잘 알려져 있다
- 크게 생성 패턴, 구조 패턴, 행위 패턴으로 나뉜다
2. 생성 패턴
클래스의 인스턴스 생성과 관련된 패턴
- Abstract Factory
- 제품과, 제품을 생성하는 팩토리에 대해 모두 인터페이스가 존재하는 패턴
class Application { private Button button; private Checkbox checkbox; public Application(GUIFactory factory) { button = factory.createButton(); checkbox = factory.createCheckbox(); } public void paint() { button.paint(); checkbox.paint(); } } public class Main { public static void main(String[] args) { // OS에 맞는 팩토리를 주입하여 일관된 UI 생성 GUIFactory factory = new MacFactory(); // or new WinFactory(); Application app = new Application(factory); app.paint(); } }
- Builder
User user = new UserBuilder() .name("wibaek") .age(24) .build();
- 생성자가 바뀌면 코드를 다 바꿔야 하니깐, 그래서 객체 생성을 명확하게 표현하기가 어려움
- 요즘은 람다 같은거 많이 쓰니깐, 그럴 때 유리. optional 처리할때랑 에러 처리할때 유리
- .마다 개행하면 어떤 라인에서 에러 추적하기가 편하다
- Factory Method
- 추상 팩토리와 팩토리의 차이점?
- abstract factory → 어떤 구현체의 뭉뚱그린것?
- 함수와 변수가 있는, 인터페이스/abstract class
- 팩토리 → 리눅스 x를 예로
- 팩토리가 버전에 따라서 다른 객체를 리턴
- 상황에 따라 동적으로 유연하게 객체를 생성할 수 있다
- Prototype
- 객체가 런타임에 스스로를 복제할 수 있게 하는 패턴
- 새로 생성된 객체는 이전 객체의 값들을 복사해서 가져온다
- Singleton
- 인스턴스가 하나만 생성되게 제한/보장
- 사용처: 하나만 생성하지 않으면 안되는 경우라서 싱글톤을 쓰는 경우도 있다
- 아키텍처/버전업시에 엄청 꼬이는 경우가 있다
- 원래 1스레드 1커넥션 → 다 커넥션으로 바꿀때, 기존 싱글톤이 병목이 될 수 있다. 그래서 싱글톤을 쓸 때 잘 생각하고 써야함
- 그리고 원자성 보장이 어려워진다. 그럼 원자성 보장이 되는 싱글톤으로 바꿔야한다…
- 옛날 spring은 autowired 시에 자동으로 싱글톤 처리를 했다.
- 그래서 디비 레플리카가 있을 때 읽기/쓰기가 달라야 하는데, mysql 커넥터를 하나만 만들어서 문제가 있기도 했다
- 그래서 레플리카 db를 쓰는 경우에는 mysql 커넥터를 2개 두는 경우가 많다
- 그래서 싱글톤을 개발 초창기에는 자주 쓰는데, 쓰다보면 위험한 경우가 많다, 그리고 디버깅이 잘 안되는 이슈가 있다
3. 구조 패턴
- Adapter
- 호환되지 않는 인터페이스를 가진 클래스들이 호환되게 변환하는 패턴
- 객체 어댑터, 클래스 어댑터 2가지 방식이 존재한다
- 객체 어댑터
- 클래스 어댑터
- 다중상속이 되는 언어가 문제다 ㅋㅅㅋ
- Bridge
- 일반적인 것처럼 interface와 interface를 implement한 class를 분리하는 방식…? 맞나요?
- jpa에서 많이 나오는 패턴
- Composite
- 개별 객체와 객체 집합을 동일하게 다룰 수 있게 하는 패턴
interface Employee { public void showEmployeeDetails(); } class Developer implements Employee { public void showEmployeeDetails() { System.out.println("Developer: " + name); } } class Directory implements Employee { private List<Employee> employeeList = new ArrayList<Employee>(); public void showEmployeeDetails() { for(Employee emp : employeeList) { emp.showEmployeeDetails(); } } }
- Decorator
- ??? ← 중요한 패턴중 하나
- 악세사리를 달아준다고 할 때,
- 무언가를 표시하는 div가 있다. div 내에 이미지가 들어갈 수 있고, 텍스트가 들어갈 수도 있는데 → 오버플로우를 달아주는 순간 → 스크롤 생성 유무를 결정 가능 → onclick등을 달수도 있고 → 이거 하나하나의 element가 decorator
- Facade(파사드, 대문)
- 다양한 인터페이스가 존재 할 때, 하나의 통합된 인터페이스로 묶는 패턴
class CPU {} class Memory {} class HardDrive {} class ComputerFacade { private CPU processor; private Memory ram; private HardDrive hdd; public ComputerFacade() { this.processor = new CPU(); this.ram = new Memory(); this.hdd = new HardDrive(); } public void start() { processor.freeze(); ram.load(0, hdd.read(0, 1024)); processor.execute(); } } public class Main { public static void main(String[] args) { ComputerFacade computer = new ComputerFacade(); computer.start(); } }
- Flyweight
- 재사용 가능한 객체 인스턴스를 공유시켜 메모리 사용량을 최소화하는 패턴
- 이때 공유되는 상태(intrinsic state)와 각각 고유한 extrinsic state가 나뉘는 것이 핵심???
- Flyweight의 factory는 키에 해당하는 Flyweight 객체를 생성하거나 반환해준다
- ?????????
- 파이썬의 클래스메소드/static method 같은 느낌
- Proxy
- 객체 생성이 복잡하거나 오래 걸릴 때 객체에 접근하기 위한 대리자를 제공하는 패턴
- 프록시와 실제 객체가 같은 인터페이스를 사용해서 프록시를 실제 객체처럼 사용할 수 있게 한다
interface Image { void display(); } class RealImage implements Image { private String fileName; public RealImage(String fileName){ this.fileName = fileName; loadFromDisk(fileName); // 무거운 작업 } private void loadFromDisk(String fileName){ System.out.println("Loading " + fileName); } public void display() { System.out.println("Displaying " + fileName); } } class ProxyImage implements Image{ private RealImage realImage; private String fileName; public ProxyImage(String fileName){ this.fileName = fileName; } public void display() { // 실제 객체가 필요할 때만 생성 if(realImage == null){ realImage = new RealImage(fileName); } realImage.display(); } } public class Main { public static void main(String[] args) { Image image = new ProxyImage("test_10mb.jpg"); // 이미지는 아직 로드되지 않음 System.out.println("Image object created."); // display()가 호출될 때 디스크에서 이미지를 로드 image.display(); System.out.println(""); // 이미지는 다시 로드되지 않음 (이미 생성되었으므로) image.display(); } }
생각보다 많이 씀, 디버그 하기 어려움
리얼 스틸 영화, 로봇 따라하는게 프록시 패턴 ㅇㅇ
4. 행위 패턴
- Chain of Responsibility
- Command
- Interpreter
- 다른 용도? → 생각보다 많이 씀
- ex) 데이터가 길어서 압축 할 때(로그등) 로그를 파싱하기 위한 패턴이 따로 있어야 함. 그럴 때 사용
- ex) 32비트를 쪼개자 16비트는 enum, 나머지는 언제 일어난건지 등, 쪼개서 32비트에 저장함
- 이걸 human readable로 바꾸기 위해서. 이걸 파싱하자~ → interpreter 패턴
- Iterator
- 컬렉션에서 데이터를 꺼내 사용할 때 내부 구조를 노출하지 않고, 반복자(iterator)를 이용해 접근할 수 있게 하는 패턴
- Mediator
- Memento
- Observer
- 객체간 1:N 관계를 부여하고, 객체의 상태가 변경됐을 때 다른 객체에 전달해주는 패턴
- pub-sub pattern → for async? → for message based process → 안쓰면 어캐 pub sub 할건데 ㅋㅋ
- → observer 쓰면 대는거안임? → 그건 polling 아닌가 → 그럼 내가 poll할 애를 알고 있어야 한다
- pub-sub - ‘eventually’
- State
- Strategy
- 알고리즘을 캡슐화 하는 패턴
- 전략
interface Strategy를 만들고StrategyA,StrategyB등을 만들어 교환해서 사용할 수 있게 함
- Template Method
- 생각보다 중요, 이미지 heic로 올리는거 처리할 때 필요함
- Visitor
C11 객체지향 설계
1. 설계 원리
- 객체지향 분석으로 기능/구조/행위 모델링을 수행한 후에는 설계 과정을 진행한다
- SW 시스템 로직 설계, 클래스/메서드 설계, 사용자 인터페이스, 자료 구조, DB 설계, 물리적인 아키텍처 설계
- 설계 과정에 적용되는 기본 원리
- 추상화, 단계적 상세화, 모듈화, 정보 은닉, 관심사의 분할
- 분석 결과물 → 설계 결과물을 위한 기법
- 팩토링(Factoring)
- 모델 요소를 모듈(예로 클래스)로 분리하는 과정
- 디컴포지션 한다음 패턴을 찾는다 라고 이해하면 됨
- 디컴포지션: 현상(기능)을 분해해서 작게작게 정리가 된다.
- 이걸 쭉 살펴보면 이걸 어떻게 처리할지 감이 온다… 그럼 패턴을 찾을 수 있다
- 파티셔닝(Partitioning)
- 큰 모델을 세부 모델로 나누는 과정
- 계층화(Layering)
- 구성 요소를 운영과 사용 환경을 고려하여 서로 다른 특징의 그룹으로 분리하는 과정
- 통상적으로 MVC 아키텍처 설계를 의미하기도 함
- 외에는 3계층 아키텍처(인터페이스/처리 로직/데이터 관리)도 있다
2. 패키지 다이어그램
패키지 다이어그램 생성
- 패키지 다이어그램: 클래스 다이어그램의 클래스간 관계를 고려해 클래스간 응집력이 높은 것들을 패키지로 묶어 표현하는 것
- 패키지 다이어그램을 작성하는 절차
- 패키지 다이어그램을 작성할 대상물 선정
- 클래스 간의 관계를 고려하여 패키지로 정의
- 일반화(Generalization) 관계를 형성하는 클래스를 하나의 패키지로 묶는다
- 집합(Aggregation) 관계를 형성하는 클래스를 하나의 패키지로 묶는다
- 클래스의 의미적 속성(멤버 변수, 멤버 함수)의 유사성을 고려하여 패키지 할 것인지 결정한다
- 패키지에 명칭 부여 ← 이름짓는게 제일 어려움
- 패키지간의 관계 부여
- 다이어그램의 프레임을 이용해 패키지 다이어그램 완성
계층화된 아키텍처 생성
- 소프트웨어 아키텍처: SW를 구성하는 컴포넌트와 이들간의 관계를 체계화하여 표현한 것
- 객체지향 SW 개발 프로젝트에서는 아키텍처 표현을 위해 3계층 아키텍처를 사용. 각각
- HCI(Human Computer Interaction) 계층: UI에 해당하는 클래스를 포함하는 계층
- PD(Problem Domain) 계층: 분석 과정에서 도출된 도메인 클래스들을 포함하는 계층
- DM(Data Manipulation) 계층: 파일또는 DB 테이블에 해당하는 데이터 클래스를 포함하는 계층
- < 열심히 안봐도 됨
- PD 계층의 클래스를 이용해 UI 클래스와 DM 계층의 데이터 클래스를 생성한다
3. 자료 구조 설계
성능에 영향을 많이 끼치고, 이후 변경이 어렵다
- 자료 구조 설계는 3계층 아키텍처에서 하위 계층을 설계하는데 필요하다
- 즉 데이터 유지/관리를 위해 파일이나 DB 테이블을 설계하는 것
- 자료 구조 설계를 위해서는 PD 계층의 모든 클래스를 살펴보고 클래스 정보로부터 자료 구조를 정의한다
- 자료 구조 설계 가이드라인
- 클래스 다이어그램으로부터 임시로 값을 저장하는 휘발성 변수를 제거한다.
- 모든 클래스를 하나의 데이터베이스 테이블로 매핑한다.
- 클래스의 멤버 변수는 테이블의 컬럼으로 매핑한다.
- 클래스의 멤버 함수는 프로그램의 함수로 매핑한다. 혹은 데이터베이스의 저장형 프로시저(Stored Procedure)로 매핑한다.
- 일대일 관계에 있는 연관관계 혹은 집합관계를 테이블의 키(Key)로 정의하는 컬럼을 추가한다.
- 다대다 관계에 있는 연관관계 혹은 집합관계에 대해 새로운 테이블을 생성하고 관련된 클래스를 연결할 키를 저장하는 컬럼을 생성한다.
- 일반화 관계에 대해서는 하위 클래스의 대응 테이블에 키를 저장할 컬럼을 추가한다.
- 이렇게 DB 테이블 구성 후 → 정규화 과정 → 인덱스 테이블을 구성
orm써서 리스트 가져왔을 때 이후에 어떻게 할 것인가의 문제
중복될일 없을 때 set/hash → set
특정 사용자들을 저장할 때 hash요! → 중복 됨? → 왜 set 안씀? → set!
자바에서 .find() 파이썬 .exist() O(n) 연산이다
python a in b → O(n) / O(1) 아 … B의 자료형에 따라 바뀜
랭킹처럼 계속 넣었다 뻈다 하는 자료구조 → deque? heap! 왜 힙인가? → 우선순위가 자동 정렬되니깐
랭킹을 리스트로 구현하면 또라이다. 이런것들 성능에 매우 중요함.
4. 사용자 인터페이스 설계
인터페이스 설계 절차
- UI 설계를 위한 절차
- 사용 시나리오 개발
- 사용자 입장에서 어떤 시나리오에 따라 시스템이 사용되는가
- 예시) 쇼핑몰에서 특정한 상품을 주문할 때, 검색을 수행 → 상품의 상세 정보를 얻음 → 장바구니에 담음 → 결제하여 구매
- 이때 각 시나리오 스템은 대응되는 유즈 케이스 시나리오 스텝과 연결된다
- 인터페이스 구조 설계
- 도출된 사용 시나리오의 각 스텝을 블록 다이어그램 형태로 도식화하는 것, 즉 윈도우 네비게이션 다이어그램을 작성하는 것
- 인터페이스 표준 템플릿 개발
- 화면 레이아웃을 설게한다
- 인터페이스 프로토타입 개발
- 템플릿을 기반으로 인터페이스 프로토타입을 개발한다
- 인터페이스 평가
- 개발된 프로토타입이 적절한지 평가한다
당연히 해야하는데, 옛날엔 ㄹㅇ 중요했다
이전에 했던 것. 무슨 테이블을 받아서 무슨 정보를 업데이트 할 것인가
인터페이스 클래스 설계
- 도메인 클래스의 모든 클래스에 대해 인터페이스 클래스로 정의한다
- 인터페이스 클래스는 스트레오타입 <<interface>>로 정의한다
- 인터페이스 클래스에 대응되는 도메인 클래스의 Public 메서드를 순수 가상 함수로 선언하여 포함한다
- 인터페이스 클래스에 정의된 메서드는 사용자 인터페이스의 메뉴와 연결된다
5. 물리 구조 설계
- 물리 구조 설계: 개발 시스템의 SW 컴포넌트를 구현할 기술과 개발된 컴포넌트를 운영 환경의 HW 플랫폼에 배치하는 내용이 담김
배치 다이어그램 작성
- 배치(Deployment) 다이어그램: 아키텍처에 나타난 모든 패키지(or 클래스)를 플랫폼에 할당하는 것
- 예시) 클라-서버 구조 SW에서 어떤 패키지를 클라에 배치할지, 어떤 패키지를 서버에 배치할지 정하는 것
- 개발하는 SW가 독립형 컴퓨터에서 운영된다면 배치 다이어그램이 특별히 필요하지 않을 수 있음
- 그러나 분산 환경이라면 1. 서버 기반 모델 2. 클라이언트 기반 모델 3. 소형 클라이언트와 서버 모델 4. 강한 클라이언트와 서버 모델중에 결정해야 한다
기술 환경 명세
- 설계 단계의 마지막 활동은 HW와 지원 SW에 대한 세부 사항을 명세하는 것이다
- 이후 구현 과정에 진입할 수 있다
C12 인스펙션
1. 인스펙션의 중요성
- SW 개발 과정에서 작성되는 모든 산출물은 이후 의사결정 정보로 활용되거나, 개발 후속 단계 진행시 입력으로 사용된다
- 따라서 산출 문서가 정확하게 작성되었는지 확인해야 한다 → 이를 인스펙션으로 확인한다
보통은 납품 직전에 진행 . . .아님 주기적으로
인스펙션의 정의
- 인스펙션이랑 체계적으로 정의된 절차를 기반으로 결함을 발견하기 위해 훈련된 엔지니어에 의해 수행되는 산출물의 동료 검토를 의미한다
인스펙션의 목적
- 오류나 결함의 원인을 발생 시점 근처에서 찾아내기 위함
- SW 사양 충족, 품질 속성을 나타내는지 확인
- 조직에서 개선되어야 할 프로세스가 무엇인지를 식별하기 위함
- 정보를 팀원과 공유하고 인스펙션 참여자에게 시스템 및 인스펙션 교육을 하기 위함
- SW 개발 활동의 모든 단계에서 인스펙션을 수행할 수 있다
- 프로젝트 계획서, 요구사항, 분석서, SW 아키텍처, 코드, 테스트 결과 등…
인스펙션 효과
- 유지보수 단계의 결함 수정 비용은 요구사항 단계보다 200배 더 높다
- 즉 초기에 인스펙션으로 결함을 제거해야 비용 절감 효과가 크다
2. 인스펙션 참여자
- 인스펙션 리더
- 전체적인 인스펙션 과정을 계획하고 조정자의 역할을 담당
- 인스펙션 기록자
- 인스펙션 수행 과정에서 나온 의견 및 토론 내용을 모두 기록하고 정리
- 인스펙터
- 인스펙션을 수행하는 사람
- 산출물 개발자
- 인스펙션에서 검토 대상이 되는 문서를 생성한 사람
- 인스펙션 발표자
- 산출물 개발자와 다른 사람으로, 작성된 내용을 읽는 역할을 수행
3. 인스펙션 절차
1. 계획 활동
- 인스펙션 리더에 의해
- 인스펙션 팀이 구성 → 회의 장소/시간 스케줄 → 검토 산출물의 진입 조건(Entrance Criteria) 점검 → 산출물의 배포 확인 → 산출물이 인스펙션을 한 번 수행하는데 적절한 규모인지 점검 → 인스펙션 수행 팀원이 산출물에 익숙한지 확인
- 인스펙터 선정 기준
- 결함이나 오류를 잘 찾아낼 전문가로 3~5인 구성
- 인스펙터 시간 스케줄
- 시간당 250~500줄 정도로 스케줄링
2. 오버뷰 활동
- 개발자가 제품의 이론적 근거, 개발 의도를 설명하고, 제품과 후솔 개발 부분 간 관계, 제품의 주요 기능, 개발에 사용된 접근 방법등을 설명
- 인스펙션 팀이 인스펙션에 익숙하고 제품에 대해 이해도가 있으면 실시하지 않는다
3. 준비 활동
- 산출물을 인스펙터가 개별적으로 검토하는 단계
- 문장 단위로 산출물을 검토하고, 체크리스트를 이용하여 오류를 찾아 폼에 기록
- 인스펙션이 완료되면 리더에게 폼을 발송
4. 인스펙션 미팅 활동
- 모든 인스펙션 역할자가 모여 검토 결과를 확인하는 활동
- 발표자가 산출물을 절 단위로 나눠 한문장씩 발표, 이때 식별한 결함/오류를 확인하고 최종 결정
- 리더는 결함의 심각성과 타입을 확정하고, 기록자는 이를 기록
SW 기능 안전이라는 항목이 존재함 → SW가 안전한지 검증하는 국제 표준 → 인증 등급을 받아야 하기에 이런 절차가 있다
한국에서는 KISA 가 준다. isms-p. 인증 의무 대상자.
5. 제3의 시간 활동
- 해결되지 못한 이슈를 해결하기 위해 토의하는 활동
6. 재작업 활동
- 결함으로 확정된 오류들을 수정하는 활동
7. 후속 활동
- 리더와 산출물 개발자가 결함 수정을 확인하는 활동
8. 인스펙션에 대한 평가
4. 소프트웨어 리뷰 활동
- 관리 리뷰(Management Review)
- 프로젝트 진척도 점검, 제약 조건 확인
- 기술 리뷰(Technical Review)
- 기술적인 관점에서 SW의 사용 적합성/사양 및 표준과의 일치 여부를 식별
- 인스펙션(Inspection)
- 소프트웨어 이상을 감지하고 식별하기 위해 검사하는 활동
- 워크스루(Walkthrough)
- 프로그래머 주도로 발생 가능 문제점, 개발 표준 위반 여부등을 조사, 기타 문제에 대해 질문/의견 제시
