Separtion of Concerns
관심사의 분리(SoC)
관심사 분리(Separation of Concerns, SoC)는 컴퓨터 프로그램을 구별된 부분으로 분리시키는 디자인 패턴으로, 이를 통해 각 부분은 개별적인 관심사에 집중하여 문제를 해결할 수 있다.
관심사(Concerns)
프로그램 내에서 특정 기능이나 책임을 수행하는 모듈, 클래스, 함수 등을 의미 한다.
즉, 소프트웨어의 시스템을 구성하는 다양한 요소들은 각각의 관심사를 가지고 동작하며, 서로 다른 관심사를 가진 요소들은 분리되어 있어야 한다는 것이 관심사 분리의 핵심 개념이다.
관심사를 분리의 장점
코드 내에서 관심사가 서로 비슷한 기능들이 묶여있으면 코드가 더 명확하고 가독성이 좋아지기 때문에 코드를 이해하기 쉬워진다.
관심사 분리를 통해 서로 다른 부분들을 쉽게 교체하거나 수정할 수 있다.
각각의 모듈(관심사)를 개별적으로 테스트하고 검증할 수 있어 테스트를 수행하기 더욱 용이 해진다.
디자인 패턴(Design Pattern)
소프트웨어 개발에서 반복적으로 발생하는 문제에 대한 해결책을 제시하는 솔루션
디자인 패턴은 다양한 상황에서 사용할 수 있는 문제 해결방법에 대한 설명 또는 템플릿이다.
Architecture
아키텍처(architecture)라는 단어의 원래 의미는 건축물의 설계나 구조를 의미한다. 이와 유사하게 소프트웨어 개발의 관점에서도 아키텍처는 소프트웨어(건축물)을 설계하고 구현하는데 있어서, 전체 시스템의 구조 및 상호작용에 대한 원칙들을 의미한다.
소프트웨어 전체 시스템의 구조
아키텍처를 설계한다는 것은 깨끗한 방의 상태를 유지하기 위해 수납 가구를 들여 놓고, 각각의 물건들을 정해진 위치에 보관하는 것과 같다.
관심사를 기준으로 아키텍처를 설계하면, 시스템을 이해하기 쉬워지며 유지 보수성이 좋아진다.
소프트웨어 개발의 핵심적인 부분이며, 소프트웨어의 품질과 성능에 큰 영향을 미친다.
아키텍처 연습해보기
아키텍처의 원칙들을 숙지한 후 적용해보기
고민이 되는 부분은 원칙에 맞게, 또는 크게 벗어나지 않는 범위 내에서 타협하여 적용해보기
각 계층이 서로 다른 역할과 책임을 가지며, 각 계층은 그 계층 위와 아래의 계층과만 소통하도록 설계된 아키텍처
사용자에게 가까운 것과 사용자에게 먼 것으로 구분한다.
각 영역은 하나의 역할, 하나의 관심사로 격리됨으로써 복잡도를 낮추게 된다.
Input, Process, Output 3단계로 구분하기
코드를 Input → Process → Output이란 단계로 적절하게 구분만 해도 코드를 이해하고 유지보수하는데 크게 도움이 된다.
일반적인 프로그램은 사용자로부터 입력(Input)을 받아 처리(Process)한 후 결과를 출력(Output)하고, 다시 사용자로부터 입력(Input)을 요청하는 순환 구조를 가지게 된다.
Input -> 프로그램 시작
Process -> 프로그램 초기화
Output -> 사용자에게 초기 UI 보여주기
Input -> 사용자의 입력
Process -> 사용자의 입력에 따라 처리
Output -> 처리 결과 보여주기
Input -> 사용자의 또다른 입력
반복
Front-End 관점에서 Layered Architecture
프론트엔드는 UI 개발과 맞물려 있기 때문에 UI의 상태에 따른 변화를 제어하는 것이 중요
데이터를 제어하는 Layer (Model or Data)
데이터를 어느 시점에 불러오고 가공할지 결정
데이터를 불러오는 영역
데이터를 가공하는 영역
UI(컴포넌트)를 제어하는 Layer (View)
UI를 제어하는 부분, 렌더링을 언제 어떻게 시킬지 결정
컴포넌트의 관심사 분리
Design에 매몰되지 말자
단순히 디자인의 외관에 집중하지 말고, 사용자 시나리오에 맞게 UI(컴포넌트)를 개발해야 한다.
즉 디자인이 동일하지만 유저 시나리오가 다르면 다른 컴포넌트이다.
Data와 View를 연결하는 Layer (Control)
Business Logic을 다루는 부분
비즈니스 로직들은 Hooks로 따로 분리해서 컴포넌트의 관심사 즉, UI와 Business Logic을 분리하자.
MFA(Micro Front Architecture)
마이크로서비스(Microservice) 패턴의 개념을 웹 프론트엔드 애플리케이션 개발에 적용한 것
큰 웹 애플리케이션을 작은 조각으로 분해하여 독립적으로 개발하고 배포할 수 있도록 구성한 것으로 분해된 작은 조각들을 "마이크로 프론트엔드(Mircro Frontend)"라 부른다.
MFA 특징
대규모 서비스를 개발할 때 용이하다.
여러 마이크로 프론트엔드를 하나로 통합하여 전체 애플리케이션을 구축하는 방식
마이크로 프론트엔드는 독립적으로 개발, 배포, 및 실행될 수 있다.
각각의 마이크로 프론트엔드는 다른 기술 스택과 프레임워크로 개발 될 수 있다.
Reactive Architecture
이벤트 중심의 프로그래밍 모델을 사용하며, 이벤트에 대한 반응으로 일어날 일을 지정하는 것
효과(Effect)와 그 효과에 대한 원인을 분리하여 코드에 복잡하게 꼬인 부분을 풀 수 있다.
반응형 아키텍처 특징
코드에 나타난 순차적 액션의 순서를 뒤집는다. (X를 하고 Y 하는 대신, X가 일어나면 언제나 Y를 한다.)
원인과 효과가 결합한 것을 분리한다.
여러 단계를 파이프라인(함수형 도구)으로 처리한다.
MVC(Model-View-Controller)
애플리케이션을 세가지 주요 요소(관심사)로 분리하여 개발하는 아키텍처
Model: 데이터와 관련된 작업을 담당, 데이터베이스에서 데이터를 가져오거나 업데이트 하는 작업
View: 사용자 UI 담당 (Front 영역), Model에서 가져온 데이터를 가공하여 보여주는 역할을 한다.
Controller: 사용자의 요청을 처리하는 역할을 수행, View와 Model 사이에서 매개체 역할을 한다.
MVC 특징
가장 대표적인 웹 설계 아키텍처
각 요소(관심사)를 독립적으로 개발할 수 있으므로 다수의 개발자들이 협업하여 애플리케이션을 구축하는데 용이하다
MVVM(Model-View-ViewModel)
MVC 패턴과 유사하지만, View와 Model 사이에 ViewModel이라는 중간 계층(레이어)가 존재한다.
Model: 데이터와 관련된 작업을 담당, (MVC 패턴과 동일)
View: 사용자 UI 담당, (MVC 패턴과 동일)
ViewModel: View에서 필요로하는 데이터를 Model에 가져와 가공하여 제공하고, View에서 발생한 이벤트를 처리하여 Model에게 전달한다.
MVVM 특징
Vue.js에서 주로 사용하는 아키텍처 (ViewModel은 Vue Instance로 대체해서 사용된다.)
ViewModel에서 데이터 변화를 감지하고, 변경된 데이터를 View에 반영한다. 즉, 양방향 데이터 바인딩을 지원한다.
Facebook에서 앱이 커질수록 복잡도가 커지는 MVC 패턴의 대안으로 Flux 아키텍처를 고안했다. 양방향 데이터 바인딩을 쓸 때 생길 수 있는 Model-View의 복잡한 관계를 겨냥해 명확히 단방향 데이터 바인딩을 강조한다.
데이터의 흐름이 한 방향으로만 흐르기 때문에 애플리케이션의 복잡도를 낮추고, 데이터 변화를 예측 가능하게 만든다.
View는 상태가 어떻게 바뀌는지 신경쓰지 않고 오로지 사용자의 인터렉션에 따른 Action을 Dispatcher를 통해서 요청함으로써 실질적으로 상태의 변경을 Store 한곳에서 관리하게 만들어 그 부분만 파악함으로써 복잡도를 낮추고 데이터 변화를 예측 가능하게 해준다.
Action: 이벤트/메시지와 같은 객체, 데이터의 변화를 일으키는 요소로, Dispatcher를 통해 데이터 변경 요청을 보낸다.
Dispatcher: (여러) Store로 Action을 전달(브로커 역할), 즉 Action에서 받은 데이터 변경요청을 Store에 전달한다.
Store(여러개): 애플리케이션의 데이터를 보관, 받은 Action에 대한 응답으로 스스로 갱신하고서 자신이 변경되었다고 모두(View)에게 알린다.
View(React): 사용자 UI를 담당하며, Store에 전달받은 데이터를 기반으로 View를 업데이트 한다.
Redux
Flux Architecture 기반으로 만들어진 상태 관리 라이브러리
단일 Store를 사용하여 보다 직관적이고 단순화된 방식으로 사용된다.
Action: 상태 변경을 설명하는 객체(Flux와 동일)
Dispatcher: Action을 Store에 알리는 용도, 즉 상태 변경 요청(Flux와 동일)
Reducer: 전달받은 액션을 통해 애플리케이션 상태를 교체하는 함수로 이전 상태를 새로운 상태로 교체한다.(순수함수)
Subscribe: 애플리케이션 상태 변경을 구독하여 상태가 업데이트 되면 등록된 리스너를 실행시킨다.
Store(단일): 애플리케이션에 상태를 제공하며 상태가 업데이트 되면 View에게 알려 다시 그린다.
Redux의 3원칙
애플리케이션의 상태는 모두 한 곳(Store)에서 집중 관리된다.(동기화 필요 X)
상태는 불변(ReadOnly) 데이터 이며, 오직 Action 만이 상태 변경을 요청할 수 있다.(예측 가능)
Reducer(함수)를 통해 상태의 최종 값만 설정한다.(단순화)
Last updated