풀스택 서버리스 프로젝트 with React - 7. 프로젝트 설계

2023. 12. 4. 19:00개인노트-인강

사이드 프로젝트:10개 기술스택으로 구현하는 풀스택 서버리스 프로젝트 with React
Part 3. 프로젝트 설계하기
Ch01. 시스템 설계

 

# 시스템 설계가 왜 필요한가요?

- 시스템의 요구사항을 충족하기 위해 필요한 아키텍처, 인터페이스 및 데이터를 정의하는 과정
- 소프트웨어를 구성하는 요소들 (a.k.a 컴포넌트) 간의 관계와 동작 메커니즘을 표현하기 위한 구조체

## 설계의 대상

관점에 따라서 어떤 것에 중점을 두느냐에 따라 설계 결과는 여러 개가 될 수 있다.
- 구조 모델(Structure) : 소프트웨어를 구성하는 여러 시스템의 구조 설계 - 구성 요소들의 결합 관계, 구조도
- 행위 모델(Behaviour) : 여러 시스템 간 동작하는 방식에 대한 설계 - 데이터의 흐름, 입/출력 순서, 처리 순서, 프로토콜 등..

## 설계 유형

- 아키텍처 설계: 소프트웨어의 전체 구조를 high-level에서 기술. 구성 요소를 정의하고 요소들 간의 관계를 정의
- 자료구조 설계:  소프트웨어의 요구사항을 충족시키기 위해 필요한 요소들을 자료구조로 변환하여 설계하는 과정
- 인터페이스 설계: 사용자와 소프트웨어 간, 소프트웨어를 구성하는 구성 요소 간 어떻게 통신하는지 protocol과 주고받을 데이터 내용 등을 설계하는 과정

## 결과물 예시

- 소프트웨어 아키텍쳐 설계 → Architecture diagram

- 데이터 베이스 설계 → Database schema

- 시스템/객체 간 상호 작용 설계 → Sequence diagram

- 상세 클래스 설계 →  Class diagram

 

# 시스템 설계 (1) - Architecture diagram

- 시스템의 전체 구조. 시스템 간의 상호 작용 및 의존성을 high-level에서 가시화 한 다이어그램
- 각 시스템이 어떻게 동작 하는지, 어떤 데이터를 어떻게 다루는지 등의 구체적인 상호작용 내용은 생략하고, 전체적인 맥락 관점에서 기술하는 것!

## 왜 사용하나요?

- 시스템이 어떤 순서로 요청을 처리 하는지, 어떤 시스템과 소통을 하는지 쉽게 이해하기 위해 사용
- 코드 만을 보고 시스템의 흐름을 파악하기는 오랜 시간이 걸리고 효율적이지 않음
- 소프트웨어의 큰 구조/그림을 한 눈에 파악 하기 위해 사용

## 언제 사용하나요?

- 요구사항이 수집되고, 초기 설계 단계에서 사용
- 새로운 팀원이 시스템 구조를 파악하기 위해
- 추가 요구사항이 수집되어, 시스템을 변경해야 할 때 참고용 및 업데이트용
- 소프트웨어의 규모가 크면 클수록 설계도의 중요도는 더 높아짐

## 어떻게 사용하나요?

1. 구성 요소 나열
- 클라이언트
    - 웹, 모바일 앱 등
- 서버/서비스
    - 내부 서비스
    - 외부 서비스
- 데이터베이스, 스토리지

 

2. 구성 요소 간 상호 작용 표기

- 화살표로 나타낸다 ⬅️ ➡️
- A ➡️ B : 구성 요소 A가 구성 요소 B를 호출
- A ⬅️ B : 구성 요소 B가 구성 요소 A에게 응답

 

추상화된 아키텍처 예시
기술셋을 정하고 난 뒤 업데이트 한 아키텍처 예시

 

# 시스템 설계 (2) - Sequence diagram

- 객체 간의 상호 작용을 시간 순으로 시각화 한 다이어그램
- 시스템의 구조에 초점을 맞춘 것이 아니라 시스템이 어떤 순서로 누구와 상호작용 하는지에 촛점을 맞춘 behaviour diagram

## 왜 사용하나요?

- 코드를 보고 시스템의 흐름을 파악하기는 매우 오랜 시간이 걸리고 어렵다
- 시스템이 어떤 순서로 요청을 처리하는지, 어떤 시스템과 소통을 하는지 쉽게 이해하기 위해 사용

## 언제 사용하나요?

- 요구사항이 수집되고, 각 시스템 혹은 객체 간의 메시징을 정의하는 설계 단계에서
- 요청을 처리하기 위해 여러 시스템/외부 서비스 간의 상호 작용이 여러 차례 일어날 때
- 요청을 처리하기 위해 시스탬 내에서 여러 객체 간의 메시지 전달이 여러 차례 일어날 때
- 요청의 흐름을 공유해야 할 때
- 새로운 시스템을 설계하거나 기존의 시스템을 확장할 때

## 어떻게 사용하나요?

### 구성 요소

- 생명선 (Lifeline) : 객체가 메모리 상에 얼마나 오래 살아있는지 나타내는 선. 아래로 내려갈 수록 시간이 경과됨을 의미.

생명선

- 객체/참여자 (Participant)

    - 사용자

    - 데이터베이스

    - 시스템

    - 클래스

 

- 메시지 (Message) : 객체간 그리고 참여자 간에 어떤 메세지를 주고 받는지를 기술하는 것. 메세지는 기본적으로 화살표로 나타낸다.

    - 동기 (Synchronous) : 동기 요청

동기 (Synchronous)

    - 비동기 (Asynchronous) : 비동기 요청

비동기 (Asynchronous)

    - 자체 (Self) : 표기하지 않아도 되지만, 중요한 것은 표기할 수도 있다.

자체 (Self)

    - 반환 (Return) : 응답에 대한 메세지

        -  동기 반환 (Sync. return)

동기 반환  (Sync. return)

        - 비동기 반환 (Async. return)

비동기 반환 (Async. return)

- 활성 상자 (Activation box) : Lifeline 위에 그려지는 네모 박스로, 이 시간 동안은 해당 객체가 활성화 되어 있는 것을 의미.

활성 상자 : 객체에 대한 활성 여부를 나타낸다.

- Guard : 단일 메세지에 대해 조건을 명시하는 방법.

e.g. name의 길이가 1 이상일 때, createGroup(name) 메시지를 전달

- Sequence Fragments : 특정 sequence 범위에 대해 조건을 명시하는 방법.

의미 : members의 길이가 1 이상이면 'render expense page'라는 것을 해라. 그리고 그 메세지를 자기 자신에서 전달해라. 그렇지 않으면(그룹 내에 member가 없으면), members page를 render 해라.

    - Alt. = If/else 문을 의미한다.

    - Loop = while 문을 의미한다.

    - Options = If 문을 의미한다.

# 시스템 설계 (3) - Class diagram

객체가 아닌 정적인 Class

- 한 시스템을 구성하는 클래스들의 구조, 속성(attribute), 메소드(method)를 시각화 한 diagram.
- 클래스의 구조클래스 간의 관계촛점을 맞춘 structural diagram.

개념부터 (정적인) 클래스는 (동적인) 객체와 다름. 정적이라 함은 시간과 조건이 고려되지 않은 것. 따라서 클래스 다이어그램에서는 sequence diagram과 다르게 조건이나 순차적인 것들이 들어가지 않는다. 철저하게 의존성을 나타내기 위한 다이어그램

## 왜 사용하나요?

- 클래스 간의 관계, 의존성을 빠르게 파악할 수 있다.
    - 새로운 요구사항이 들어왔을 때, 재사용하거나 확장할 만한 클래스가 있는지 빠르게 파악 가능.
- 소프트웨어가 완성된 후 구현 설명을 위해 사용할 수 있다.
    - 새로운 팀원이 왔을 때 빠르게 시스템 구조를 파악할 수 있다.

e.g. 50 개의 클래스가 있을 때, 50 개 파일을 다 열어두고 비교해가며 구조를 파악하는 것은 효율적이지 않음.

## 언제 사용하나요?

- 요구사항이 수집되고, 시스템 내의 클래스 설계 단계에서
- 클래스 간의 관계가 복잡할 때 (상속과 조합이 많을 때)
- 시스템에서 사용되는 클래스들의 구조를 시각화 해야 할 때
- 새로운 시스템을 설계하거나 기존의 시스템을 확장할 때(참고용으로)

## 구성 요소

- 클래스

    - 속성 (Attribute)

    - 메소드 (Method)

- 관계

    - 상속 (Inheritance)

    - 조합 (Composition)

### 클래스

### 관계

- 상속 (Inheritance)

 

- 조합 (Composition)

# [실전] 시스템 설계 (1) - Architecture diagram

## LucidChart 툴을 사용

https://lucid.co/

LucidChart 홈페이지

- 왜?
    1. 드래그앤 드랍으로 설계 가능
    2. 다양한 아이콘 지원

## 결과물예시

결과물 예시

예) Software Requirement의 story를 보며 DB가 필요한지 확인해 보자.

# [실전] 시스템 설계 (2) - Sequence diagram

## Plant UML 사용

1. 사용하기 쉽고, Eclipse, VSCode 등 다양한 플러그인 지원
- UML syntax를 이용하여 다이어그램 이미지 파일 자동 생성

### 시작하기

1. 자바 설치. 참고 문서 → https://www.java.com/en/download/
2. GraphViz도 설치. 참고 문서 → https://plantuml.com/ko/graphviz-dot
3. VS Code marketplace에서 PlantUML 플러그인 설치
[PlantUML - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)
1. 프로젝트 폴더 아래에  `/docs` 폴더 생성
2. `sequence_diagram.plantuml` 파일 생성
3. Participant 선언
    1. User, Database, Web client, DutchPay server
4. Participant 끼리 어떤 순서대로 메시지를 주고 받을 것인지 정의

### 사용방법

https://plantuml.com/ko/

# [실전] 시스템 설계 (3) - Class diagram for 프론트 엔드

## 프론트 엔드 설계란?

- 프론트엔드의 아키텍처를 설계할 수도 있고, 컴포넌트 간 의존 관계를 나타낸 다이어그램을 그려볼 수도 있습니다.
- 더치페이의 프론트엔드 아키텍처 자체는 심플하기에, 리액트 컴포넌트 간의 의존성을 나타내기 위한 클래스 다이어그램을 그려봅니다.

## 잘 설계하기 팁

1. 페이지별로 컴포넌트를 정의한다
2. UI 디자인을 살펴보면서 공통된 요소들이 있는지 파악
    → 공통된 요소들에 대해 컴포넌트화 (DRY;Don’t Repeat Yourself 원칙)
    → 페이지 별로 컴포넌트를 계층화 해서 트리 구조로 만들 수 있겠다.
3. 사용할 만한 컴포넌트 디자인 패턴은 어떤 것이 있는가?

    a. Container 패턴: UI를 렌더링하는데에 집중하는 컴포넌트, 데이터 불러오기 등의 비지니스 로직을 담아둘 Container 컴포넌트로 나눠 설계

Container 패턴

    b. Provider 패턴: 컴포넌트 내 props drilling (프로퍼티 내리꽂기; 컴포넌트 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정 중 하나로, props를 오로지 하위 컴포넌트로 전달하는 용도로만 사용)을 방지하고자 생긴 패턴. React Context나 Redux/Recoil과 같이 중앙 상태 관리를 이용하여 데이터를 저장해 두고, 필요한 모든 컴포넌트 (i.e. Consumer)에서 이 데이터에 접근 가능하도록 한 패턴.

Provider 패턴

4. 각 컴포넌트에 최소한으로 필요한 props는 무엇일지 정의

    a. 어떤 데이터들을 컴포넌트들 끼리 주고받아야 할 지 생각해보기

    b. 각 컴포넌트 별로 state/props를 미리 생각해보는 것도 도움이 된다.

5. 한 컴포넌트가 하나의 책임만 가지고 있는지 확인 (Single Responsibility Principle)

    a. 더치페이 예시 - 한 컴포넌트 내에서 그룹 생성하는 것 뿐만 아니라 그룹을 삭제하는 UI/로직까지 담고 있다면 이 컴포넌트는 너무 많은 것을 핸들링 하려고 하는 것 ➡️  쪼갭시다!

- 읽어보면 좋을 자료: https://reactjs.org/docs/thinking-in-react.html