득이공간

[소프트웨어공학] 4장. 설계 본문

CS/소프트웨어공학

[소프트웨어공학] 4장. 설계

쟁득 2024. 2. 24. 14:45
해당 게시물은 김정욱 교수님의 '소프트웨어공학' 강의를 수강하며
학습한 내용을 개인적으로 정리한 글입니다.

📌 목차 - 4장. 설계

4-1. 설계
4-2. 객체 지향 모델링 (UML)
4-3. 정적 모델링 - 클래스 다이어그램
4-4. 동적 모델링
4-5. 동적 모델링 - 순서 다이어그램
4-6. 동적 모델링 - 상태 다이어그램
4-7. 동적 모델링 - 활동 다이어그램
4-8. 절차 지향 모델링 (DFD)
4-9. 설계 요령
4-10. 아키텍처 설계
4-11. UI 설계


📌 4-1. 설계

* 설계
- 개발될 제품에 대한 의미있는 공학적 표현으로, 설계자는 다양한 제약 조건을 만족시킬 수 있는 최적의 설계안을 만들고, 설계를 평가할 기준도 정량적으로 명시해야 한다.
- How(어떻게) 관점에서 바라본다.

* 좋은 설계
- 요구분석명세서의 내용을 모두 포함해야 하고 변화에 쉽게 적응할 수 있어야 한다.

* 설계 종류
- 상위 설계: 아키텍처, DB, UI
- 하위 설계: 컴포넌트, 자료구조, 알고리즘

* 설계 방식
- 절차 지향 설계(DFD): 어떠한 절차를 거쳐서 작업을 수행하는지에 초점을 둔다.
- 객체 지향 설계(UML): 객체들의 상호작용에 초점을 둔다.

* 설계 방식 비교
- 목적의 차이
- DFD: 시스템 내의 데이터 흐름과 처리를 나타내는 데 사용 // 데이터 플로우와 처리 프로세스 시각화
- UML: 시스템이나 소프트웨어의 다양한 측면을 모델링하는 데 사용 // 아키텍처, 클래스, 상호작용 및 상태
- 적용 분야의 차이
- DFD: 데이터 처리와 데이터 플로우가 중요한 시스템, 특히 정보 시스템 및 업무 프로세스 모델링에 사용한다.
- UML: 객체 지향 소프트웨어 개발 및 시스템 아키텍처 모델링을 위한 표준 모델링 언어로 널리 사용한다.

* 설계 원리(객체 지향 설계)
- 분할과 정복: 큰 문제를 소 단위의 모듈로 나눈다. 각 모듈끼리 소통하는 방법이 필요하고 복잡도 vs 처리의 용이성을 결정한다. (모듈을 작게 쪼갤수록 소통으로인한 복잡도 증가)
- 추상화: 필수 정보만 추출해서 강조해서 본질적인 문제에 집중할 수 있도록 한다. (과정 추상화: 알고리즘 형태 / 데이터 추상화: 데이터 구조 형태 / 제어 추상화: 여러 줄의 내용을 간략하게 줄인다.)
- 캡슐화: 사용자에게 해당 객체의 기능(서비스)과 사용법만 제공하고 내부는 함부로 변경하지 못하도록 감춘다.
- 정보은닉: 외부에서 객체의 내부를 들여다보지 못하도록 한다.
- 상속: 상위 클래스의 모든 것을 하위 클래스가 물려받아서 사용한다.
- 다형성: 어떤 객체의 속성이나 기능이 상황에 따라 여러가지 형태를 가질 수 있다.


📌 4-2. 객체 지향 모델링 (UML)

* UML 모델링
- 객체지향 프로그램 설계를 표현하기 위해 사용하는 표기법으로 시스템을 가시화, 명세화, 문서화한다.

* UML 관점
- 기능적 관점: 요구분석 단계 - 유스케이스 다이어그램
- 정적 관점: 시스템의 구조 - 클래스 다이어그램
- 동적 관점: 시스템의 내부 동작 - 순서 다이어그램, 상태 다이어그램, 활동 다이어그램

* UML 모델링 과정
1. 유스케이스 다이어그램 작성
2. 개념적인 객체 모형을 작성
3. 순서 다이어그램 작성
4. 객체 모형 완성(속성, 오퍼레이션, 관계)
5. 상태, 활동 다이어그램 작성

* 객체지향 모델링
- 정적 모델링: 클래스 다이어그램
- 동적 모델링: 순서 다이어그램, 상태 다이어그램, 활동 다이어그램


📌 4-3. 정적 모델링 - 클래스 다이어그램

* 클래스 다이어그램
- 과정
1. 클래스 및 속성 찾기
2. 관계 찾기
3. 클래스 다이어그램 그리기
- 구성
- 클래스 이름, 속성(+, #, -, ~, /, _), 메서드

* 클래스 사이의 관계
- 일반화 관계 (상속 관계): 부모를 향한 화살표로 표시. 클래스(실선), 인터페이스(점선)
- 연관 관계 (독립 관계): 양방향(실선), 단방향(실선화살표)
- 집합 관계 (상하 관계): 전체 객체를 향한 빈 마름모 화살표. 전체 객체의 라이프 타임과 부분 객체의 라이프 타임이 독립적이다.
- 합성 관계: 전체 객체를 향한 색 마름모 화살표. 전체 객체의 라이프 타임과 부분 객체의 라이프 타임이 의존적이다.

* 클래스 사이의 숫자
- 참조 가능한 인스턴스의 수: 1, 0..1, *, 1..*, n..m

* 클래스 다이어그램 장단점
- 장점: 설계관점에서 구체적이고 클래스 간의 관계를 빠르고 명확하게 알 수 있다.
- 단점: 너무 상세한 내용을 기입하면 구현단계에서 할 일이 미리 이뤄지는 오류를 범할 수 있다.


📌 4-4. 동적 모델링

* 동적 모델링
- 클래스들의 상호작용이나 클래스의 상태 변화 등 시스템 내부의 동작을 모델링한 것
- 순서 다이어그램: 객체들이 어떻게 상호 동작하는지를 메시지 순서에 초점을 맞춰 나타낸 것
- 상태 다이어그램: 복잡한 객체의 상태 변화를 나타낸 것으로, 이벤트 발생에 의해 객체가 어떻게 변화하는지 나타낸다.
- 활동 다이어그램: 절차나 작업의 흐름을 나타낸 것으로, 순차/병렬적 작업인지, 어떤 작업과 동기화가 되어야 하는지를 나타낸다.

* 순서 vs 활동 다이어그램
- 순서: 객체 중심. 객체간 어떤 메시지를 주고받는가
- 활동: 액티비티 중심. 어떻게 객체들이 소통하는가

* 동적 다이어그램 사례
- 순서 다이어그램: 하나의 시스템 안에서 객체 간의 메시지를 주고받는 것을 표현한다.
(온라인 쇼핑 시스템에서 사용자 상호 작용의 흐름, 소프트웨어 구성 요소 간의 메서드 호출 순서)
- 상태 다이어그램: 한 객체의 상태 및 상태 변화를 표현한다.
(신호등의 상태 분석, 문의 상태 분석)
- 활동 다이어그램: 시간에 따른 시스템 전체의 흐름을 표현한다.
(주문 처리 시스템의 단계 모델링, 승인 프로세스의 워크 플로우)


📌 4-5. 동적 모델링 - 순서 다이어그램

* 순서 다이어그램 구성요소
- 액터
- 객체: (인스턴스이름:클래스이름), (인스턴스이름:클래스이름)) <- 인스턴스 모임
- 생명선: 객체의 생성, 소멸, 활성화될 때를 나타내는 선 (위->아래, 점선). 액터나 객체가 얼마나 오래 존재하는지 나타낸다. 객체가 소멸되면 X 표시
- 활성 박스: 객체가 다른 객체와 상호작용하며 활성화되고 있음을 표현한다. 일반적으로 요청과 응답으로 구성된다.
- 메시지: 객체간 주고받은 데이터. 일반적으로 요청과 응답으로 구성된다.
- 동기 메시지(Synchronous message): 요청을 보낸 후 반환이 올때까지 기다린다. (색이 채워진 화살표)
- 비동기 메시지(Asynchronous message): 요청을 보낸 후 반환을 기다리지 않고 다른 작업을 수행한다. (일반 화살표)
- 자체 메시지(Self message): 자기 자신에게 요청을 보낸다.
- 반환 메시지(Reply/Return message): 요청에 대해 메시지를 반환한다.
- 프래그먼트: 순서 다이어그램에서 범위를 명시하기 위한 표현이다. 여러 생명선과 활성을 포괄적으로 감싸는 박스형태로 표현한다.
- 옵션(opt): if, switch
- 대안(alt): else if 같은 대안이 있는 조건문. 점선으로 구분한다.
- 반복(loop): 반복문, for, while
- 병렬(Par): 병렬처리, 동시에 수행

* 순서 다이어그램의 장단점
- 장점
- 메시지의 순서 또는 시간 순서를 명확하게 보여준다.
- 객체 간의 상호작용을 한눈에 볼 수 있다.
- 단점
- 복잡한 상호 작용을 표현하기 어렵다.
- 객체 간의 관계가 바뀌었을 때 이미 만들어진 순서 다이어그램 변경이 상대적으로 어렵다. (시간에 대한 고려가 이미 고정)


📌 4-6. 동적 모델링 - 상태 다이어그램

* 상태 다이어그램
- 특정 클래스의 객체의 상태가 이벤트가 발생하거나 시간의 흐름에 따라 바뀌는 것을 그림으로 시각화 한 다이어그램

* 상태 다이어그램 용도
- 한 객체의 상태 변화를 상세히 분석
- 객체의 동적 상태 변화를 정의하고 분석하는 목적
- 이벤트에 의한 객체의 반응 분석
- 객체의 속성이나 동작 검증
- 향후 클래스 다이어그램에 정의된 클래스의 속성과 동작의 적합성을 검증할 수 있다.

* 상태 다이어그램 구성요소
- 시작 상태: 검정 동그라미
- 종료 상태: 검정 동그라미 + 흰 동그라미
- 상태 (state): 사각형
- 상태 전환 (transition): 화살표
- 이벤트: <<이벤트이름>> 상태1-트리거[가드]/액티비티->상태2
- 트리거: 상태 변화를 유발하는 이벤트
- 가드: 전이가 이루어지는 Boolean 조건
- 액티비티: 전이 동안 수행되는 행동
- 프레임: 상태 다이어그램의 범위


📌 4-7. 동적 모델링 - 활동 다이어그램

* 활동 다이어그램
- 시스템이 어떻게 동작하는지, 시스템의 전체 흐름을 모델링한다.

* 활동 다이어그램 구성요소
- 시작점에서 출발해서 액티비티를 거쳐서 끝나는 흐름
- 분기: 둘 중 어떤 것을 선택할지 나누는 흐름
- 병렬: 두 가지 업무가 동시에 진행된다.
- 파티션: 액티비티를 진행하는 객체에 따라 파티션을 나눌 수 있다.

* 활동 다이어그램 용도
- 유스케이스 다이어그램의 실현화: 유스케이스들 사이에 발생하는 흐름을 명확하게 표현할 수 있다.

* 활동 다이어그램 장점
- 업무 흐름을 분석할 때 사용한다.
- 코드 실행 흐름을 분석할 때 사용한다.


📌 4-8. 절차 지향 모델링 - DFD

* 데이터 흐름도 (DFD: Data Flow Diagram)
- 구조적 방법론을 대표하는 다이어그램 (절차지향)
- 데이터가 소프트웨어 내의 각 프로세스를 따라 흐르면서 변환하는 모습을 나타낸 다이어그램

* 데이터 흐름도 구성요소
- 프로세스: 입력 데이터를 원하는 데이터로 변환하여 출력하기 위한 과정 // 원으로 표현, 원 안에 이름 부여
- 데이터 흐름: 구성요소들 간의 인터페이스를 나타낸다.
- 데이터 저장소: 데이터가 저장되어있는 집합 (정지한 데이터) // 두 개의 직선으로 평행선, 평행선 안에 데이터 저장소 명칭 부여
- 외부 엔티티(Entity): 데이터의 흐름도를 주도하는 객체 // 사각형으로 표현

* 데이터 흐름도 작성방법
1. 프로세스의 입출력 데이터 흐름 식별
2. 외부 엔티티 정의
3. 데이터 흐름 식별
4. 데이터 흐름 명칭 부여
5. 프로세스 명칭 부여
6. 데이터 저장소 정의
7. 검토 및 보완

* 데이터 흐름도 작성규칙
1. 데이터 보존의 원칙: 출력 데이터 흐름은 반드시 입력 데이터 흐름을 이용해서 생성해야 한다.
2. 최소데이터 입력의 원칙: 반드시 필요한 입력 데이터 흐름만을 입력해야 한다.
3. 지속성의 원칙: 항상 수행할 준비를 갖추고 있어야 한다.
4. 순차처리의 원칙: 데이터를 도착 순서대로 처리해야 한다.
5. 영구성의 원칙: 데이터는 처리된 후 없어져야 한다.
6. 데이터 변환의 원칙
(1) 본질의 변환: 입력 데이터 흐름에 프로세스(편집, 계산)를 통해 출력 데이터 흐름을 산출한다.
(2) 합성의 변환: 2개 이상의 입력 데이터 흐름에 대해서 하나의 출력 데이터흐름을 산출할 수 있다.
(3) 관점의 변환: 입력 데이터 흐름에 실제적인 변경을 하지 않는다. (데이터를 거절 또는 출력)
(4) 구성의 변환: 출력 데이터는 입력 데이터와 동일하지만, 데이터 구성 형태가 변환
7. 독립성의 원칙: 프로세스는 자신의 입력 데이터와 출력 데이터에 대해서만 알면 된다.

* 데이터 흐름도 장단점
- 장점
- 명확성과 간결성: 데이터의 흐름을 명확히 볼 수 있어서 시스템의 기능을 이해하는데 도움이 된다.
- 의사소통: 개발자 등 이해관계자 간 효과적인 의사소통 도구로 사용한다.
- 단점
- 세부사항 부족: 복잡한 시스템의 경우 모든 데이터 흐름을 그리기 어렵다.
- 사용자 인터페이스나 하드웨어 구성요소 등의 시스템의 다른 측면을 포착하기는 어렵다.
- 객체 지향 구조에 대해서는 표현이 어렵다.


📌 4-9. 설계 요령

* 좋은 설계란?
- 모든 소프트웨어 설계 기술의 목표: 복잡한 문제를 단순한 조각으로 자르는 것
- 성능을 높이는 방법: 간결함
- 바람직한 설계 목표: 느슨한 결합(모듈 간), 강한 응집력(각 모듈 내부)

* 설계 기본 개념
- 전통: 6가지 원리(분할과 정복, 추상화, 캡슐화, 정보은닉, 상속, 다형성)
- 최근: 아키텍처를 고려, 모듈화에 초점

* 모듈화
- 모듈: 시스템의 각 기능
- 모듈의 독립성
(1) 결합도(Coupling)를 약하게
(2) 응집도(Cohesion)를 강하게
(3) 모듈의 크기가 작을 때

* 결합도와 응집도
- 이 두가지 핵심 개념은 소프트웨어 시스템의 유지보수성, 확장성, 신뢰성을 결정하는 중요한 요소다.
- 결합도: 소프트웨어 모듈 간 상호 의존 정도
- 응집도: 모듈 내 요소들이 하나의 목적을 달성하기 위해 작동하는 정도

* 결합도
- 모듈 간의 상호 의존하는 정도, 두 모듈 사이의 연관관계
- 결합도는 약할수록 좋다.
- 종류: (1)약 ... (6)강
(1) 자료 결합도: 모듈 간에 단순히 파라미터 등을 통해 데이터를 주고 받는다. (가장 바람직)
(2) 스탬프 결합도: 두 모듈이 동일한 자료구조를 참조하는 형태다. 자료구조의 형태가 변경되면 그것을 참조하는 모든 모듈에 영향을 준다.
(3) 제어 결합도: 다른 모듈의 제어요소가 파라미터를 통해 전달되는 경우다. (상위 모듈이 하위 모듈의 처리 절차를 알고 있어서 이를 통제한다.)
(4) 외부 결합도: 어떤 모듈에서 외부로 선언한 데이터를 외부의 다른 모듈에서 참조하는 경우다.
(5) 공통 결합도: 여러 모듈이 하나의 데이터 영역을 참조해서 사용하는 경우다. ex. 전역변수
(6) 내용 결합도: 어떤 모듈이 다른 모듈의 내부 기능과 데이터를 직접 참조하는 경우다. ex. public (가장 좋지 않음)

* 응집도
- 한 모듈 내부의 처리 요소들이 서로 관련이 되어있는 정도, 하나의 기능을 중심으로 책임이 잘 뭉쳐 있는지
- 응집도는 높을수록 좋다.
- 종류 (1)높은 ... (6)낮음
(1) 기능적 응집도: 모든 요소들이 하나의 기능을 수행하기 위해 구성된다. (가장 바람직) - 같은 일을 같이한다.
(2) 순차적 응집도: 모듈 내 하나의 활동으로부터 나온 출력 데이터를 그 다음 활동의 입력 데이터로 사용한다. - 같은 일을 각각 순차적으로 한다.
(3) 교환적 응집도: 요소들이 동일한 데이터를 조작해서 한 그룹 안에 모여있다. - 서로 다른 일을 같이한다.
(4) 절차적 응집도: 모듈이 다수의 관련 기능을 가질 때, 요소들이 그 기능을 순차적으로 수행한다. - 서로 다른 일을 각각 순차적으로 한다.
(5) 시간적 응집도: 연관된 기능 없이 특정 시점에 처리되어야하는 활동들을 한 모듈에서 처리한다.
(6) 논리적 응집도: 같은 범주의 기능을 수행해서 그룹으로 묶였으나 본질적으로 다르다.
(7) 우연적 응집도: 요소들 간 아무런 관계가 없다. (가장 좋지 않음)

* 결합도 장단점
- 결합도가 낮을 때 장점: 향상된 유지보수성, 향상된 모듈성, 향상된 확장성
- 결합도가 높을 때 단점: 복잡성 증가, 유연성 감소, 모듈화&재사용성 감소

* 응집도 장단점
- 응집도가 높을 때 장점: 가독성 및 이해성 향상, 오류 격리 개선, 신뢰성 향상
- 응집도가 낮을 때 단점: 코드 중복 증가, 기능 저하, 난해한 모듈 이해

* 모듈 설계 방안
- 유지보수가 용이해야 한다.
- 결합도를 최대한 낮추고 응집도를 높인다.

* 팬인 (Fan-in) / 팬아웃 (Fan-out)
- 팬인: 자신을 호출하는 모듈 수
- 팬아웃: 자신이 호출하는 모듈 수

* 시스템 복잡도
- 팬인은 높게, 팬아웃은 낮게 설정할수록 시스템의 복잡도를 최적화할 수 있다.
- 팬인이 높을수록
- 다른 모듈이 해당 모듈을 많이 사용 -> 재사용 측면에서 잘된 설계
- 단일 장애점(SPOF: Single Point Of Failure) 발생 가능
- 관리 비용 및 테스트 비용 증가
- 해당 모듈을 많이 사용한다고 해서 결합도가 높은 것은 아니다.
- 팬아웃이 낮을수록
- 해당 모듈이 다른 모듈을 적게 사용 -> 재사용 측면에서 잘된 설계
- 팬아웃이 높으면
- 해당 모듈이 다른 모듈을 많이 사용 -> 불필요한 모듈 호출 여부 검토 필요

* 설계 요령
- 최상위 모듈의 결합은 줄이고, 응집은 높이도록 노력
- High Fan-out은 줄이도록 노력
- 각 모듈이 너무 많은 내용을 포함하지 않도록 노력
- 모듈의 영향권을 그 모듈의 하위에 두도록 노력

* 설계 진행
- 객체 지향 모델링을 위해 학습한 3가지 모델링 기법(기능적, 정적, 동적)을 바탕으로 구체적인 설계를 진행한다.
(1) 아키텍처 설계: 요구분석 단계 후 찾아낸 클래스와 메서드 교통정리
(2) DB 설계: 데이터베이스에 대한 상세한 데이터 모델을 작성
(3) UI 설계: 사용자와 효과적으로 상호작용하기 위한 인터페이스를 설계


📌 4-10. 아키텍처 설계

* 아키텍처 설계
- 설계와 시공에 대한 가이드가 될 큰 밑그림
- 중요한 이유: 시스템이 개발된 뒤에는 구조를 바로잡기 어렵다.
- 목적: 품질을 유지, 비기능적 요구사항에 나타난 제약을 반영, 기능적 요구사항을 구현하는 방법을 찾는 것

* 아키텍처 중요성
- 소프트웨어가 어떤 구조고 어떻게 동작할 것인지를 예측할 수 있으며, 변경에 유연하게 대처 가능하다.

* 아키텍처 4+1 관점
- 시스템의 여러 측면을 고려하기 위한 다양한 관점 정의


* 문제영역 1: 시나리오 관점
- 최종 사용자가 인식하는 시스템의 기능에 주목한다. -> 유스케이스 관점
- 유스케이스 다이어그램


* 해법영역 1: 논리적 관점
- 분석가/설계자: 클래스나 컴포넌트의 종류와 관계
- 시스템 내부의 클래스나 컴포넌트 및 이들의 관계에 초점을 둔다.
- 클래스 다이어그램, 순서 다이어그램(클래스 간 상호작용), 활동 다이어그램(클래스의 연산동작)


* 해법영역 2: 프로세스 관점
- 시스템 통합자: 시스템의 성능, 확장성, 효율
- 비기능적인 속성에 관심을 가진다.
- 자원의 효율적인 사용, 병행 실행, 비동기, 이벤트 처리 등을 표현한다.
- 순서 다이어그램, 상태 다이어그램(서로 다른 객체의 연관성), 활동 다이어그램


* 해법영역 3: 개발 관점
- 프로그래머: 서브시스템의 모듈 구조와 관계
- 서브시스템의 모듈이 어떤 관계를 갖는지에 주목한다.
- 독립적으로 실행되는 컴포넌트와 이들 간 관계를 정의한다.
- 순서 다이어그램, 상태 다이어그램(서로 다른 객체의 연관성), 활동 다이어그램


* 해법영역 4: 물리적 관점
- 시스템 엔지니어: 시스템의 구성
- 시스템을 구성하는 장치 간의 물리적인 배치에 주목한다.
- 물리적 노드 프로세스의 분산 및 배치 상태를 나나탠다.
- 순서 다이어그램, 상태 다이어그램(서로 다른 객체의 연관성), 활동 다이어그램

* 아키텍처 스타일
- 개발할 시스템의 타입에 따라 아키텍처 스타일을 결정한다.


* MVC 구조 스타일 - MVC(Model/View/Controller) 패턴
- 아키텍처를 설계할 때 참조할 수 있는 헤결방식 (가장 널리 쓰인다.)
- 프로그램 구성 요소들을 별도의 컴포넌트로 분리한다.
- 모델: 데이터 관련 객체
- 서브시스템의 핵심 기능과 데이터를 가지고 있다.
- 사용자가 원하는 모든 데이터를 가지고 있어야 한다.
- 모델은 뷰와 컨트롤러에 의존해서는 안된다.
- 오로지 '데이터'에 대한 정보만 존재하는 것이 바람직하다.
- 뷰: 사용자에게 보여지는 객체
- UI를 담당한다.
- 사용자가 원하는 모든 데이터를 가지고 있어야 한다.
- 뷰는 모델에만 의존해야 하고, 컨트롤러에는 의존하면 안된다.
- 컨트롤러: 모델과 뷰를 연결하는 객체
- 모델과 뷰의 중개자 역할을 한다.
- 사용자로부터 받은 입력을 기반으로 모델과 뷰를 제어한다.
- 컨트롤러는 모델과 뷰에 의존해야 한다.
- 동작 순서
(1) 컨트롤러로 사용자의 입력이 들어온다.
(2) 컨트롤러는 모델의 데이터를 업데이트하고 모델을 호출한다.
(3) 컨트롤러는 모델을 나타낼 뷰를 선택한다.
(4) 뷰는 모델을 통해 화면에 데이터를 나타낸다.
- 장점
- 역할 분담을 통해 프로그램의 독립성이 높아진다.
- 개발 환경 변경에도 유연하게 대응할 수 있다.
- 단점
- 뷰와 모델 사이의 의존하는 정도가 높다.
- 입출력 조건이 복잡해질수록 뷰와 컨트롤러의 의존성이 높아진다.


* 저장소 구조 스타일
- 서브시스템들이 단일 중앙 저장소의 자료를 접근하고 변경한다.
- 데이터가 중앙에 위치해서 서브시스템 사이의 병렬처리와 통합문제를 다룰 때 용이하다. (은행시스템)
- 장점
- 낮은 결합성: 접근자 사이에 느슨한 결합을 유지한다.
- 높은 확장성: 각 접근자의 수정, 확장이 용이하다.
- 단점
- 단일 장애지점: 공유 데이터의 장애로 전체가 장애를 일으킬 수 있다.


* 클라이언트/서버 구조 스타일
- 서버가 클라이언트에 서비스를 제공한다.
- 서버: 강력한 성능으로 자원을 관리하며 클라이언트가 요청하는 기능이나 자원을 제공한다.
- 클라이언트: 서버에 있는 자원의 사용을 위해 서버에 접속한다.
- 장점
- 데이터 집중화: 데이터의 구성과 관리를 단순화할 수 있다.
- 보안: 인증이 완료된 클라이언트만 서비스에 접근하도록 한다.
- 단점
- 병목: 클라이언트가 증가하면 서버의 부하가 올라가 네트워크 속도가 느려진다.
- 비용: 설치 및 관리 비용이 일반적으로 높다.
- 단일 장애지점: 서버가 고장나면 클라이언트는 더이상 작동할 수 없다.


* 계층 구조 스타일
- 시스템이 계층적으로 분할되어있다.
- 서브시스템이 하나의 계층이 되어 하위 층이 제공하는 서비스를 상위 층의 서브시스템이 사용하도록 구성한다. (컴퓨터네트워크 OSI 7 레이어)
- 추상화: 필수 정보만 추출해서 강조한다.
- 캡슐화: 자세한 데이터나 메서드, 자원, 구현 등이 각 층 안에 캡슐화되어있다.
- 장점
- 추상화: 각 층의 역할과 책임, 관계를 잘 이해할 수 있다.
- 캡슐화, 응집, 결합: 각 층의 응집이 높고 층 사이의 결합이 적다.
- 재사용성: 각 층의 의존도가 적어서 쉽게 다른 모듈로 교환할 수 있고, 다른 시스템에 사용 가능하다.
- 단점
- 이웃 층과의 커뮤니케이션이 제한적이다.


* 파이프 필터 구조 스타일
- 서브시스템이 입력 데이터를 받아 처리하고 결과를 다른 시스템에 보내는 작업이 반복된다.
- 필터: 서브시스템
- 파이프: 서브시스템 사이의 관계
- 필터들은 서로 독립적이어서 상태를 공유하지 않는다. (컴파일러)
- 장점
- 단순성: 시스템을 일련의 입력, 출력, 변환으로 쉽게 볼 수 있다.
- 재사용: 다른 응용프로그램에서 필터를 쉽게 재사용할 수 있고 교체를 할 수도 있다.
- 병렬성: 병렬 처리로 구현하기 쉬운 아키텍처를 제공한다.
- 단점
- 자원의 낭비: 시간과 공간을 낭비할 수 있다.
- 오류는 별도 출력 스트림으로 처리해야 한다.

* 아키텍처 스타일별 설계 원리 반영
- 분할 정복
- 계층 구조 스타일: 분리된 계층이 독립적으로 설계된다.
- 클라이언트/서버 구조 스타일: 클라이언트와 서버로 확실히 분리된다.
- MVC 구조 스타일: 세가지 컴포넌트가 독립적으로 설계될 수 있다.
- 응집도 증가
- 계층 구조 스타일: 각 계층 마다 응집도가 크다.
- 클라이언트/서버 구조 스타일: 서버가 클라이언트에게 응집도 높은 서비스를 제공한다.
- MVC 구조 스타일: 뷰와 제어부분이 단일 UI 계층에 같이 있다면 계층 응집도가 크다.
- 결합도 감소
- 계층 구조 스타일: 잘 설계된 하위층은 상위층에 대해서 알지 못한다.
- 클라이언트/서버 구조 스타일: 분산된 컴포넌트들 사이에 통신 채널이 유일하다.
- MVC 구조 스타일: 세 컴포넌트 사이의 통신 채널이 최소화 된다.
- 추상화 증진
- 계층 구조 스타일: 상위층을 설계할 때 하위층이 어떻게 구현되었는지 상세히 알 필요가 없다.
- 클라이언트/서버 구조 스타일: 분산된 컴포넌트를 분리함으로써 좋은 추상성을 가진다.
- 재사용성 증진
- 계층 구조 스타일: 하위층은 범용적으로 설계되어 다른 시스템에서 같은 서비스를 제공하도록 재사용될 수 있다.
- 융통성
- 계층 구조 스타일: 새로운 기능을 하위층 서비스에 추가하거나 상위층을 교체할 수 있다.
- 클라이언트/서버 구조 스타일: 서버와 클라이언트를 추가해서 쉽게 분산 시스템을 재구성할 수 있다.
- MVC 구조 스타일: 뷰, 제어를 변경해서 UI를 쉽게 갱신할 수 있다.


📌 4-11. UI 설계

* UI (사용자 인터페이스)
- 넓은 의미: 사용자와 시스템 사이에서 의사소통을 할 수 있도록 고안된 물리적, 가상의 매개체
- 좁은 의미: 소프트웨어 등에서 사람이 접하는 화면
- 사용 목적: 높은 사용성(Usability), 심리학에 기반해서 사용자가 필요로 하는 요소를 쉽게 찾고 사용하도록

* UI 중요성
- 사용자 경험 개선
- 생산성 향상: 사용자가 빠르게 작업을 수행할 수 있도록 하는 것이 중요하다. (시간, 노력 절약)
- 에러 감소 (안정성)
- 유지보수 용이성
=> 시장 경쟁력 강화

* UI 종류
- GUI: 사용자가 그래픽을 통해 정보를 교환한다. (아이콘과 텍스트로 이루어진 객체를 조작)
- 웹 인터페이스: 인터넷과 웹 브라우저를 통해 조작한다.
- 명령어 인터페이스: 정해진 명령어를 입력해서 시스템을 조작한다. (cmd)
- 텍스트 사용자 인터페이스: 자연어를 입력해서 시스템을 조작한다. (챗봇, 게임)

* UI 설계 요소
- 버튼: 현재 화면의 작업과 관련된 단일, 독립적인 작업에 사용
- 툴바: 공통 작업의 경우 사용
- 메뉴: 여러 화면에 적용될 수 있는 작업에 사용
- 체크 박스: boolean 타입, 다른 항목과 관련 없이 한 항목을 선택하는 on/off 스위치에 사용
- 라디오 버튼: 하나의 선택만 가능한 경우 사용
- 텍스트: 사용자가 임의의 내용을 입력하게 할 때 사용. 오류가 들어올 가능성을 전제로 구현해야 한다.
- 리스트: 주어진 것을 모두 보여주고 그 중 선택하게 하고 싶을 때 사용
- 콤보 박스: 스크롤 형태의 리스트
- 탭: 여러 스크린 영역을 수시로 이동하게 하고 싶을 때 사용, 병렬적으로 프로세스 돌릴 때
- 다이얼로그 박스: 임시 화면이나 옵션을 제시할 때 사용

* 좋은 UI를 위한 설계 지침
(1) 사용하기 쉽게 직관적이어야 한다. (가시성)
(2) 사용하기 편리해야 한다. (사용성)
(3) 도움말을 제공해야 한다.
(4) 사용자의 데이터 입력을 제어할 수 있어야 한다.
(5) 사용자의 입력에 반응해야 한다. (피드백)
(6) 일관성을 유지해야 한다.
(7) 입력 작업은 최소로 해야한다.
(8) 삭제 또는 취소 버튼 클릭시 재확인을 요구해야 한다.

* UI 설계 과정
1. 사용자 분석: 사용자 유형(숙련된 사용자, 초보자)에 맞게 UI를 설계
2. 태스크 분석: 소프트웨어가 수행할 작업을 분석, 유스케이스 별로 UI 흐름 파악
3. 설계와 구현: 분석한 유스케이스를 기반으로 디자인하고 코드를 구현
4. 사용성 테스트: 낮은 오류율, 높은 만족도, 높은 예측가능성을 만족하는지 테스트