소프트웨어공학: 두 판 사이의 차이
잔글
→소프트웨어 개발 프로세스: 이전에 기록했던 잘못된 정보 제거
잔글 (→소프트웨어공학의 필요성) |
잔글 (→소프트웨어 개발 프로세스: 이전에 기록했던 잘못된 정보 제거) |
||
| 21번째 줄: | 21번째 줄: | ||
* 요구사항 분석(Requirement Analysis): 목표를 정확히 확인하는 시스템 요구사항 분석은 보통 기술적 소양과 원활한 의사소통 능력이 있어야 한다. 또한 객관적 관점을 가지고 다양한 고객의 관점을 통합하고 요구사항 명세를 작성하는 혜안이 필요하다. 이에 따라 모델링을 할 때에는 기능별로 연산과 제약조건을 기술하는 기능 관점에 따른 , 시스템의 상태와 변화 원인을 기술하는 동적 관점, 정보를 담은 객체 사이의 관계를 기술하는 정보 관점을 성공적으로 통합하여 데이터가 어떻게 처리되는지 묘사하는 Entity-Relationship Model을 그리는 Class Diagram(객체 다이어그램), Finite State Machine(유한 상태 기계, 상태 다이어그램으로 분류되기도 하다)을 묘사하는 State Diagram(상태 다이어그램), Data Flow Diagram(자료 흐름도, .DFD)을 구성하게 된다.<ref>여담으로, Data Flow Diagram과 State Diagram은 컴퓨터 하드웨어 설계(집적 회로)/소프트웨어 설계(컴파일러 등)에 직접 활용하기도 하며, ER 모델을 묘사하는 객체 다이어그램은 데이터베이스 이론에서 주로 쓰던 거다. 개발 프로세스에 대한 연구에 이 개념들을 가져온 건 일종의 응용법이다.</ref> 이에 따라 클래스 다이어그램을 그리는 객체 모델링 -> 상태 다이어그램을 그리는 동적 모델링 -> 자료 흐름도를 그리는 기능 모델링 순서로 요구사항을 정리하게 되는데, 이 방법은 럼바우 분석 기법(Rumbaugh analysis)이라고 불린다. | * 요구사항 분석(Requirement Analysis): 목표를 정확히 확인하는 시스템 요구사항 분석은 보통 기술적 소양과 원활한 의사소통 능력이 있어야 한다. 또한 객관적 관점을 가지고 다양한 고객의 관점을 통합하고 요구사항 명세를 작성하는 혜안이 필요하다. 이에 따라 모델링을 할 때에는 기능별로 연산과 제약조건을 기술하는 기능 관점에 따른 , 시스템의 상태와 변화 원인을 기술하는 동적 관점, 정보를 담은 객체 사이의 관계를 기술하는 정보 관점을 성공적으로 통합하여 데이터가 어떻게 처리되는지 묘사하는 Entity-Relationship Model을 그리는 Class Diagram(객체 다이어그램), Finite State Machine(유한 상태 기계, 상태 다이어그램으로 분류되기도 하다)을 묘사하는 State Diagram(상태 다이어그램), Data Flow Diagram(자료 흐름도, .DFD)을 구성하게 된다.<ref>여담으로, Data Flow Diagram과 State Diagram은 컴퓨터 하드웨어 설계(집적 회로)/소프트웨어 설계(컴파일러 등)에 직접 활용하기도 하며, ER 모델을 묘사하는 객체 다이어그램은 데이터베이스 이론에서 주로 쓰던 거다. 개발 프로세스에 대한 연구에 이 개념들을 가져온 건 일종의 응용법이다.</ref> 이에 따라 클래스 다이어그램을 그리는 객체 모델링 -> 상태 다이어그램을 그리는 동적 모델링 -> 자료 흐름도를 그리는 기능 모델링 순서로 요구사항을 정리하게 되는데, 이 방법은 럼바우 분석 기법(Rumbaugh analysis)이라고 불린다. | ||
* 설계(Design): 프로그램의 구조도(structure chart)를 그리기 위해 소프트웨어 디자인 패턴을 도입한다. 이들은 생성 패턴, 구조 패턴, 행동 패턴으로 다시 나뉜다. | * 설계(Design): 프로그램의 구조도(structure chart)를 그리기 위해 소프트웨어 디자인 패턴을 도입한다. 이들은 생성 패턴, 구조 패턴, 행동 패턴으로 다시 나뉜다. | ||
** 생성 패턴: 자원을 사용하는 코드를 작성하는 패턴이다. 추상 팩토리<ref>객체(클래스)의 집합을 생성하기 위해 인터페이스 개념으로 객체의 틀만 잡아 놓고 구현은 자식에서 한다는 팩토리 개념을 활용해 단계적으로 집합을 구성</ref>, 빌더<ref>객체의 표현 방법과 생성 방법을 분리하여 부모 객체에 메서드나 기본 변수를 다 정의한 후 자식 객체에서 생성자로 서로 다르게 초기화함</ref>, 의존성 주입(Dependency Injection)<ref>클라이언트에게 무엇을 할 지 일일이 구현하는 대신 클라이언트 객체에서 메서드 명만 호출하기만 하면 서비스 객체가 알아서 하는 부분을 늘리는 방법이다.</ref>, 팩토리 메서드<ref>부모 객체에서 모든 메서드를 다 구현하고 자식 객체에서는 오버라이드하여 변종 기능을 구현하는 방법. 추상 팩토리와 달리 부모 메서드가 부모 객체에서 이미 구현되어 있을 때 이렇게 부른다.</ref>, 지연된 초기화(Lazy Initialization)<ref>코드에서 사용하는 변수의 초기화는 그 변수를 사용하는 시점 직전에 초기화한다는 원칙 | ** 생성 패턴: 자원을 사용하는 코드를 작성하는 패턴이다. 추상 팩토리<ref>객체(클래스)의 집합을 생성하기 위해 인터페이스 개념으로 객체의 틀만 잡아 놓고 구현은 자식에서 한다는 팩토리 개념을 활용해 단계적으로 집합을 구성</ref>, 빌더<ref>객체의 표현 방법과 생성 방법을 분리하여 부모 객체에 메서드나 기본 변수를 다 정의한 후 자식 객체에서 생성자로 서로 다르게 초기화함</ref>, 의존성 주입(Dependency Injection)<ref>클라이언트에게 무엇을 할 지 일일이 구현하는 대신 클라이언트 객체에서 메서드 명만 호출하기만 하면 서비스 객체가 알아서 하는 부분을 늘리는 방법이다.</ref>, 팩토리 메서드<ref>부모 객체에서 모든 메서드를 다 구현하고 자식 객체에서는 오버라이드하여 변종 기능을 구현하는 방법. 추상 팩토리와 달리 부모 메서드가 부모 객체에서 이미 구현되어 있을 때 이렇게 부른다.</ref>, 지연된 초기화(Lazy Initialization)<ref>코드에서 사용하는 변수의 초기화는 그 변수를 사용하는 시점 직전에 초기화한다는 원칙.</ref>, 싱글턴 및 멀티턴 패턴<ref>객체 내에 그 객체 타입의 인스턴스(초기화된 객체)를 저장하여 한 객체에 하나 또는 객체 개념에 의해 관리되는 여러 개의 인스턴스를 보관하고 Get 메서드로 가져오게 한다. 이러면 단 하나의 인스턴스만 전역으로 선언하고 그 이상의 인스턴스는 전역 인스턴스 내에 저장하게 된다. 변수 내 인스턴스들이 코드 이곳저곳에 흩어지지 않고 한 곳에 모여 구현 단계에서 관련된 코드 관리가 쉽다는 장점이 있으나 역으로 시험 단계에서 객체와 인스턴스 갯수가 일치할 때 쉬워지는 유닛 테스트를 어렵게 하는 단점이 있다.</ref>, 프로토타입 패턴<ref>먼저 모든 객체의 원형을 만든 다음 거기서 모든 객체를 파생시키는 방법. HTML5 및 자바스크립트의 기본 객체인 Object가 프로토타입 패턴 프로그래밍을 강제하는 좋은 예시이다.</ref> 등이 있다. | ||
** 구조 패턴: 작성한 코드를 배치하는 패턴이다. 어댑터 패턴<ref>클래스 초기화를 할 때 원하는 인터페이스를 선택하여 저장하고 초기화하도록 생성자를 제공</ref>, 브리지 패턴<ref>구현부와 추상적 구조 선언을 동등하게 분리하고 클래스에서 인터페이스을 가져와 메서드 초기화를 진행</ref>, 컴포지트 패턴<ref>트리 구조의 다이어그램을 먼저 그려 직관적인 상속 구조를 도식화함</ref>, 데코레이터 패턴<ref>특정 작업을 한다고 클래스 구현 이전에 표식(데코레이터)을 정의에 남겨두는 방법이다.</ref>, 퍼사드(Facade) 패턴<ref>라이브러리 단위에서 메서드에 대해 선언만 하고 특정 구현이 필요하다고 강제하는 퍼사드 클래스를 정의하여 개별 소프트웨어들의 동작이 라이브러리 동작에 의존하게 되며 발생하는 문제를 줄이는 효과를 준다.</ref>, 플라이웨이트(Flyweight) 패턴<ref>유사한 객체들은 최대한 많은 컴퓨팅 자원을 공유하게 하여 메모리 사용을 줄이는 방법</ref>, 프록시 패턴<ref>호출 전용 프록시 객체를 본 객체와 따로 두어 프록시 객체가 조건에 따라 적절한 본 객체를 가리키게 하는 방법. 플라이웨이트 패턴과 결합한 메모리 최적화도 가능하다.</ref>, 모듈 패턴<ref>파일 단위로 존재하는 모듈 내에 관련된 변수와 객체, 메타데이터를 모아놓고 소프트웨어 작성 시점에 사전 정의된 모듈의 기능을 불러오는 방법</ref> 등 다양한 종류가 있다. | ** 구조 패턴: 작성한 코드를 배치하는 패턴이다. 어댑터 패턴<ref>클래스 초기화를 할 때 원하는 인터페이스를 선택하여 저장하고 초기화하도록 생성자를 제공</ref>, 브리지 패턴<ref>구현부와 추상적 구조 선언을 동등하게 분리하고 클래스에서 인터페이스을 가져와 메서드 초기화를 진행</ref>, 컴포지트 패턴<ref>트리 구조의 다이어그램을 먼저 그려 직관적인 상속 구조를 도식화함</ref>, 데코레이터 패턴<ref>특정 작업을 한다고 클래스 구현 이전에 표식(데코레이터)을 정의에 남겨두는 방법이다.</ref>, 퍼사드(Facade) 패턴<ref>라이브러리 단위에서 메서드에 대해 선언만 하고 특정 구현이 필요하다고 강제하는 퍼사드 클래스를 정의하여 개별 소프트웨어들의 동작이 라이브러리 동작에 의존하게 되며 발생하는 문제를 줄이는 효과를 준다.</ref>, 플라이웨이트(Flyweight) 패턴<ref>유사한 객체들은 최대한 많은 컴퓨팅 자원을 공유하게 하여 메모리 사용을 줄이는 방법</ref>, 프록시 패턴<ref>호출 전용 프록시 객체를 본 객체와 따로 두어 프록시 객체가 조건에 따라 적절한 본 객체를 가리키게 하는 방법. 플라이웨이트 패턴과 결합한 메모리 최적화도 가능하다.</ref>, 모듈 패턴<ref>파일 단위로 존재하는 모듈 내에 관련된 변수와 객체, 메타데이터를 모아놓고 소프트웨어 작성 시점에 사전 정의된 모듈의 기능을 불러오는 방법</ref> 등 다양한 종류가 있다. | ||
** 행동 패턴: 개별 기능의 형태를 명시하는 패턴이다. 책임 연쇄<ref>명령 객체를 가공하는 여러 객체들을 순차적으로 배치하고 연쇄적으로 처리를 시도하는 패턴</ref>, 커맨드 패턴<ref>invoker가 보낸 커맨드 객체를 Receiver가 받아 처리하며 client는 어떤 리시버가 어떤 명령어를 처리할지 지정만 한다</ref>, 인터프리터 패턴<ref>Context 코드가 딸린 Expression을 자료구조에 쌓아 놓은 다음 적절한 순회 방법을 골라 처리함</ref>, 반복자 패턴(Iterator를 만들어 리스트를 순회하며 명령을 처리), 중재자 패턴<ref>모든 객체가 중재자 객체를 통해서만 상호작용하는 패턴</ref>, 메멘토 패턴<ref>Originator 객체에 CareTaker 객체가 Memento 객체 생성을 요청한 다음 Memento 객체에만 데이터 변경 작업을 한 후 반환하여 Originator를 유지하는 방법. Seed 데이터를 사용하는 난수 생성 기능이 이런 식으로 구현된다.</ref>, 발행-구독 패턴<ref>비동기 통신 알고리즘을 객체 간 상호작용에 적용하여 메세지를 주고 받는 코드 패턴</ref>, 상태 패턴<ref>State를 이동하면서 각 State에 지정된 처리를 시행하는 패턴. 소프트웨어 내 Main Loop가 이 패턴을 쓰는 경우가 많다.</ref>, 전략 패턴<ref>서로 다른 알고리즘에 따라 작동하는 객체 내 메소드를 조건에 따라 상호 교체하는 기법</ref>, 템플릿 메소드<ref>모형이 되는 개별 메소드 내의 서브 메소드의 호출 순서를 정해놓고 객체 별로 서브 메소드의 구현을 다르게 지정할 수 있는 패턴</ref>, 비지터 패턴<ref>객체 내에 서로 다른 서브 객체들의 인스턴스들을 두고 생성자에서 어떤 객체로 초기화하냐에 따라 상위 객체의 메소드가 사용하는 서브 객체가 달라짐</ref> 등이 있다. | ** 행동 패턴: 개별 기능의 형태를 명시하는 패턴이다. 책임 연쇄<ref>명령 객체를 가공하는 여러 객체들을 순차적으로 배치하고 연쇄적으로 처리를 시도하는 패턴</ref>, 커맨드 패턴<ref>invoker가 보낸 커맨드 객체를 Receiver가 받아 처리하며 client는 어떤 리시버가 어떤 명령어를 처리할지 지정만 한다</ref>, 인터프리터 패턴<ref>Context 코드가 딸린 Expression을 자료구조에 쌓아 놓은 다음 적절한 순회 방법을 골라 처리함</ref>, 반복자 패턴(Iterator를 만들어 리스트를 순회하며 명령을 처리), 중재자 패턴<ref>모든 객체가 중재자 객체를 통해서만 상호작용하는 패턴</ref>, 메멘토 패턴<ref>Originator 객체에 CareTaker 객체가 Memento 객체 생성을 요청한 다음 Memento 객체에만 데이터 변경 작업을 한 후 반환하여 Originator를 유지하는 방법. Seed 데이터를 사용하는 난수 생성 기능이 이런 식으로 구현된다.</ref>, 발행-구독 패턴<ref>비동기 통신 알고리즘을 객체 간 상호작용에 적용하여 메세지를 주고 받는 코드 패턴</ref>, 상태 패턴<ref>State를 이동하면서 각 State에 지정된 처리를 시행하는 패턴. 소프트웨어 내 Main Loop가 이 패턴을 쓰는 경우가 많다.</ref>, 전략 패턴<ref>서로 다른 알고리즘에 따라 작동하는 객체 내 메소드를 조건에 따라 상호 교체하는 기법</ref>, 템플릿 메소드<ref>모형이 되는 개별 메소드 내의 서브 메소드의 호출 순서를 정해놓고 객체 별로 서브 메소드의 구현을 다르게 지정할 수 있는 패턴</ref>, 비지터 패턴<ref>객체 내에 서로 다른 서브 객체들의 인스턴스들을 두고 생성자에서 어떤 객체로 초기화하냐에 따라 상위 객체의 메소드가 사용하는 서브 객체가 달라짐</ref> 등이 있다. | ||