✅ 설계 원리
요구 분석
: ‘무엇을 만들 것인가’를 다루는 작업
설계
: ‘어떻게 실현할 것인가’를 구체적으로 결정하는 활동
1) 기본 구조 설계 – 아키텍처 설계로 각 모듈의 역할과 인터페이스를정의
2) 상세 설계 – 모듈 내부의 알고리즘, 데이터를 명세화
고객, 사용자로부터 요구사항과 프로토타이핑을 개발자가 파악하는 것을 요구 분석이라고 한다.
고객과 사용자가 솔루션을 제공하면 그에 맞게 개발자 쪽에서 설계를 한다고 보면 된다.
설계는 개발자들의 창의성이 들어가게 되는 과정이고 설계는 분석 모델링과 함께 작업이 이루어질 수도 있음, 커뮤니케이션이 굉장히 중요함
✔요구 분석에서 설계로
- 요구 분석 작업을 통하여 무엇을 개발할 것인가를 결정한 후에는 도메인 영역의 문제에 집중하여 모델링한다
🔽설계
- 추상화
- 모듈
- 정보은닉
- 인터페이스 분리
- 의존 관계 역전
✔설계 기본 개념
- 설계
- 높은 수준의 의사 결정 과정의 연속
- 설계 원리가 중요
- 전통적 설계 방법 : 분할 정복, 추상화, 합성 등의 원리를 적용
- 최근의 방법 : 아키텍처 기반의 설계 방법
- 아키텍처 이해 : 서브시스템, 모듈의 개념과 설계 작업의 관점, 설계 작업 과정을
숙지해야함
✔아키텍처
- 시스템을 구성하는 컴포넌트와 컴포넌트 상호작용의 집합
- 컴포넌트 : 독립적 으로 취급할 수 있는 단위
- 서브시스템(모듈) : 시스템의 복잡도를 줄이기 위하여 분할한 것
✔설계 관점과 표현 방법
모듈 관점
: 일정한 책임을 구현한 코드 단위인 모듈과 그 관계
컴포넌트 관점
: 실행될 때 동작하는 요소와 상호작용
할당 관점
: 소프트웨어의 하드웨어 설치, 작업 할당, 구현, 데이터 저장에 대한 관점
✔설계 작업 과정
- 의사 결정 과정이면서 동시에 시스템을 알아가는 과정
- 시스템의 유형이 아키텍처 스타일 선택에 중요한 영향을 줌
- 예를 들어 대화형 시스템은 주로 객체 구조 스타일을 사용하고 임베디드 시스템은 이벤트 스타일을 사용한다.
- 설계 결과에 많은 영향을 줌
- 만약 시스템 유형이 정해져 있지 않을 때는 아키텍쳐를 직접 설계해야함
- 설계 목표 설정
- 전체 시스템에 대한 설계 목표를 파악하고 결정한다
- 예를 들어 전화 교환 시스템을 개발한다면 고장에 대한 내성(fault tolerance), 안전과 보안, 최대 성능이 설계 목표가 될 수 있다
- 스타일 결정
- 시스템이나 서브시스템의 타입을 결정하기 위하여 설계 목표와 유형에 맞은 아키텍처 스타일을 선택한다.
- 적용할 수 있는 아키텍처 스타일이 있다면 이를 적용하여 시스템의 표준 아키텍처를 설계한다. 없다면 맞춤형 아키텍처를 설계한다
- 서브시스템의 기능, 인터페이스 명세
- 서브시스템 사이의 인터페이스를 정의하고 서브시스템 사이의 상호작용을 위한 동작을 작성
- 아키텍처 설계 검토
- 설계한 아키텍처가 요구, 설계 목표, 설계 원리를 잘 만족하는지 검토
✔설계가 중요한 이유
한번 설계된 시스템의 경우에는 변경이 쉽지 않은데, 추후에 발생될 수 있는 변화와
새로운 시스템과의 연계 등을 고려해야 함
통합(강하게 결합된 경우) 잘 다루지 못하면 문제가 될 수 있음
[온톨로지 예시]
오른쪽 구조처럼 테이터 베이스를 숨기기 위해서 데이터 베이스 래퍼를 개발한 모습이다.
이러면 데이터베이스에서 변경되거나 갱신된 데이터들을 보호할 수 있게 되고 래퍼만 수정하면 된다.
🔽품질 목표
- 품질 제약사항은 설계에 대한 목표가 될 수 있음
-
비기능적인 요구를 설계 목표로 구체적으로 명시
-
다른 속성에 영향을 미치는지를 꼭 고려해야하고 그런 것들을 반영을 해서 설계
-
이를 만족시키기 위하여 설계안을 만들고 그 중에 최적 안을 골라내는 작업
✔품질 특성
- 국제표준 ISO 25010 정의 소프트웨어의 기능 외적 품질
✔전통적인 설계 원리
효율성(efficiency)
단순성(simplicity)
단순성 | 효율성 | 분할, 계층화 | 추상화 | 모듈화 |
---|
복잡한 여러 가지 요소를 교통정리 하여 단순화 하거나 복잡함 최소화 | 사용한느 자원이 적정하고 효과적이도록 한다. | 다루기 쉬운 덩어리로 분리하여 계층화한다. | 자세한 부분에 좌우되지 않게 컴포넌트를 정의한다 | 각 모듈이 외부와의 결합이 낮고 내부 요소가 응집되도록 한다. |
이중에서 단순성과 효율성이 가장 중요
▶추상화
- 대상에 대하여 특정한 목적에 관련된 정보에 집중하고 나머지 정보는 무시하는 관점
- 동작하는 것에 대한 초점을 둔 정의, 복잡성을 줄이고 복잡한 속도의 시스템을 효율적으로 다루고 구성할 수 있게하는 것을 의미 → 설계과정에서 필수적
- 컴포넌트의 추상화는 유지보수 단계에서 아주 중요
- 데이터나 절차적인 동작 관점으로 정의 : 클라이언트와 서버의 정보교환을 주고받는 메시지의 추상화
▶캡슐화
- 추상화된 대상이 제공하는 서비스를 쉽게 접근하게 하는 개념
- 정보 은닉(information hiding) → 내부에 데이터가 어떻게 저장이 되는지 어쩧게 처리가 되는지 제공을 어떻게 하는지 공개되어있지 않음.
▶모듈화
- 문제를 소프트웨어의 구성요소가 될 만한 수준으로 분할하는 과정 → 가능한한 가장 잘게 분할될때까지..
- 소프트웨어를 작은 구성 요소, 즉 패키지 또는 클래스로 나누는 것
- 모듈을 수정해도 전체 시스템을 수정할 필요가 없기 때문에 효율적
- *단점 : 모듈이 다수로 늘어나면 상호작용에서 살짝 에러가 있거나 비효율적일 수 있음.*
🔽추상화, 캡슐화, 모듈화
추상화
– 시스템의 핵심 특성에 초점을 두어 하나의 큰 시스템을 분할하는 원리
캡슐화
– 분할된 핵심 정보만을 노출
큰 시스템을 잘 모듈화
된 시스템으로 완성
🔽결합
- 모듈 간에 서로 의존하는 정도 -
모듈 간 인터페이스 수/ 각 인터페이스의 복잡성
내용 결합(content coupling)
‐ 한 모듈이 다른 모듈의 내용을 직접 참조(강한 결함)
공통 결합(common coupling)
‐ 한 모듈이 다른 모듈이 읽은 전역 변수 값을 쓰거나 변경
제어 결합(control coupling)
‐ 한 모듈이 다른 모듈의 제어흐름 경로를 결정
스탬프 결합(stamp coupling)
‐ 복합 데이터 구조의 일부만 사용하는 모듈에 복합 데이터 구조 전달할 때
데이터 결합(data coupling)
‐ 모듈들이 주고받는 매개변수가 간단한 타입이거나 레코드 안의 필드이더라도 단순 타입인 경우(느슨한 결합)
🔽응집
하나의 모듈 안에서 수행되는 작업들이 서로 관련된 정도
- 모듈 안의 여러 요소들이 하나의 목적을 위하여 유기적으로 관련되어 있는 것이 제일 좋음
- 높은 응집
- 재사용하기도 쉽고 이해하기도 좋으며
- 수정에 의하여 받는 영향이 적다
우연적(coincidental) 응집
단위 안의 요소들이 의미적으로 아무관계가 없음 (낮은 응집)
논리적(logical) 응집
본질적으로 다르더라도 같은 범주의 기능을 수행하므로 논리적으로 분류
시간적(temporal) 응집
프로그램 실행의 특정한시간에 처리되므로 한그룹 안에 모여 있는 경우
절차적(procedural) 응집
모듈 안에서 수행되는 연산이 프로그램에서 수행되는 순서와 관련
교환적(communicational) 응집
모듈의 내부 요소들이 동일한 데이터를 조작하기 때문에 그룹화 된 경우
기능적(functional) 응집
하나의 기능에 모두 기여하고 밀접하게 관련(높은 응집)
🔽객체지향 설계 원리
상속과 인터페이스 등 새로운 구문과 함께 발전
💡 1. 단일 책임의 원리(Single Responsibility Principle)
2. 개방 폐쇄의 원리(Open Close Principle)
3. 리스코프 교체의 원리(Liskov Substitution Principle)
4. 인터페이스 분리의 원리(Interface Segregation Principle)
5. 의존관계 역전의 원리(Dependency Inversion Principle)
✔인터페이스와 구현의 분리
인터페이스
: 공개된 메소드의 프로토타입만을 정의해 놓은 것
- 공개된 메소드를 인터페이스로 따로 정의하고 이를 구현 상속
- 컴포넌트의 공개 인터페이스를 컴포넌트가 어떻게 구현되는지 상세하게 나타낸 것과 분리
✔단일 책임의 원리
클래스의 역할과 책임을 단일화 하여 클래스를 변경해야 할 이유를 하나로 제한
개방 폐쇄의 원리
- 소프트웨어 개체(클래스, 모듈, 기능 등)가 확장을 위해서는 열려 있어야 하지만 수정을 위해서는 닫혀야 한다
상속
: 다형성이 적용되어 서로 대체할 수 있는 인터페이스를 구현
- sort 함수의 알고리즘이 수정이 필요할 때에는 클라이언트 수정에는 영향이 가지않도록 해야하는 원리이다.
✔리스코프 교체의 원리
- 클래스 B가 클래스 A에서 상속받은 하위 유형이라면 프로그램의 동작을 방해하지 않고 A를 B로 대체할 수 있어야 한다
- 하위 클래스는 클라이언트의 관점에서 기능을 손상시키지 않는 방식으로 상위 클래스 메소드를 대체 가능해야 한다
✔인터페이스 분리의 원리
- 클라이언트가 사용하지 않는 인터페이스를 강제로 구현해서는 안됨
- 비만 인터페이스(fat interface)
- 오염된 인터페이스(polluted interface)
✔의존 관계 역전의 원리
- 구체화 된 모듈이 추상화 된 모듈에게 의존이 역전되도록 설계
🔽설계 메트릭