Home [프론트엔드] 소프트웨어 아키텍처와 디자인패턴(2)
Post
Cancel

[프론트엔드] 소프트웨어 아키텍처와 디자인패턴(2)

시작하며

이전시간에는 집을 설계하는 방법인 소프트웨어 아키텍쳐에 대해 공부해 보았다. 이번에는 디자인 패턴에 대해 볼텐데, 신기한 부분이 있었다. 가장 초기모델인 MVC 에 대해서인데, 이것을 아키텍처라고 정의하는 사람도 있고, 디자인 패턴이라고 하는 사람도 있다. 무엇이 맞는것일까..? 어디로 분류하냐가 중요한 부분일까에 대해서도 고민해 보았다.

우선적으로 아키텍처는 설계 및 구조라고 할 수 있고, 디자인패턴은 특정 기술문제를 해결하기 위해 쓴다는 것이다. MVC 를 아키텍처로 확장시킬 수 있고, 디자인패턴으로도 쓸 수 있다는 게 나의 생각이다.

1. 가장 초기버전인 MVC design-pattern(a.k.a. architecture)

3개의 main components:

  • Model
  • View
  • Controller

MVC Architecture

Model

  • 모델은 데이터를 논리적으로 다루는 컴포넌트.
  • 모델은 Controller 의 request 에 응답하는데, Controller는 그 자체로는 db에 접근하거나 요청하지 않기 때문.
  • Model 은 View 와 직접적으로 소통하지 않는다.

View

  • 유저를 위해 UI 를 보여준다.
  • Model 컴포넌트에서 가공된 데이터는 컨트롤러를 통해 View 에서 보여준다.
  • View 는 Model 에서 일어나는 로직을 몰라야함.

Controller

  • View 와 Model 을 연결하는 다리 역할
  • handling data logic 에 대해 걱정할 필요가 없음. 왜냐? Model 이 할 일만 알려주면 되기 때문.
  • Model 에서 데이터를 받아오고, 어떻게 유저에게 보여줄지 설명한다.

MVC 의 장점과 단점

장점

  • 유저 인터페이스를 비즈니스 로직에서 분리할 수 있다.
  • 컴포넌트는 재사용이 가능하다.
  • 유지보수가 용이하다.
  • 컴포넌트별로 테스트가 가능함.

단점

  • 복잡도가 높다.
  • 간단한 어플리케이션에는 어울리지 않는다.
  • View 에서 데이터 엑세스의 비효율성이 있다.

MVC 가 나눠진 이유

  1. 화면을 다루는 문제와 데이터를 다루는 문제의 성격이 달라서 분리하고 싶음
  2. Model과 View 간의 의존관계를 최소화 하여 화면의 수정이 데이터수정에 영향을 미치지 않고 데이터 수정이 화면의 수정에 영향을 미치지 않고자 함.

초창기 웹서비스의 MVC 아키텍처

아키텍처의 잣대와 범주는 언어마다 / 환경마다 다 다르다. 초창기 시절의 MVC는

  • 데이터베이스를 Model
  • HTML 과 CSS, javascript 까지 포함한 클라이언트 영역을 View
  • 그 가운데서 라우터를 통해 데이터를 처리하고 새로운 HTML 을 만들어서 보여주는 백엔드 영역을 Controller라고 했다.

jQuery 시절의 MVC 아키텍처

이후 프론트엔드 역할이 추가되고, ajax 라는 기술이 만들어지면서 이제는 HTML 을 서버에서 직접 만들 필요가 없게 되었다. 이때는 MVC 의 개념이 조금 바뀌게 된다.

  • ajax 로 부터 받는 데이터를 Model
  • HTML 과 CSS 로 만들어지는 화면을 Vuew로 취급
  • javascript 가 중간에서 서버의 덷이터를 받아 화면을 띄우고, 이벤트를 처리해서 서버에 데이터를 전달하는 Controller 역할.

기존의 서버 라우터에서 하던 어떤 역할들이 이제 클라이언트의 자바스크립트가 처리하게 되었고, Database는 백엔드의 역할이며 REST API 의 ajax 데이터가 Model 이 된다.

2. MVVM 아키텍처 - angular, react, vue

2013년에 구글에서 앵귤러가 발표 된다. 앵귤러에서 템플릿바인딩이라는 중요한 개념들이 등장했고, 이후로 웹 개발하는 방식의 패러다임이 완전하게 바뀌게 된다.

Model 이 변하면 View 를 수정하고, View에서 이벤트를 받아서 Model를 변경한다는 Controller 의 역할은 그대로인데 이를 구현하는 방식이 jQuery 와 같은 DOM 조작에서 템플릿과 바인딩을 통한 선언적인 방법으로 변하게 된다.

선언적인 방법이란?

  • VanillaScript 는 DOM 에 직접 접근하고 수정하는 것( 명령형 ), 애플리케이션 규모가 커지면 커질수록 관리 힘듬.
  • 개발자들은 애플리케이션에서 보여주고 싶은 핵심 UI를 “선언”하기만 하면 실제로 DOM 을 조작해서 UI 를 그려내고, 변화시키는 일은 라이브러리나 프레임워크가 대신해주는 방식을 찾게 됨. ( 선언적 개발</span> )

3. Component & Container-Presenter 패턴

MVVM을 얻은 웹 프론트 엔드 개발은 생산성이 크게 늘었다. DOM API 를 잘 다루지 못하더라도 비즈니스로직에만 집중한다면 금방 금방 서비스를 만들 수 있게 되었다.

웹 서비스가 발전하게 되면서 이제는 하나의 Page 단위가 아니라, Page 안에 여러가지 Module 이 있고, Modal 이나 여러 화면들이 하나의 화면에서 구성이 될 수 있도록 발전하게 되었다.

그래서 MVVM 이 이제는 화면단위가 아니라 조금 더 작게 재사용 할 수 있는 단위로 만들어서 조립하는 방식으로 발전하게 된다.

이것이 우리에게 익숙한 Component 패턴이다.

컴포넌트는 재사용이 가능해야 한다는 원칙에 따라 가급적 비즈니스 로직을 포함시키지 않으려고 개발했다. 비즈니스 로직이 들어가게 되면 컴포넌트의 재활용성은 상당히 떨어지게 된다.

  • Container Component: 비즈니스 로직을 관장하고 있는 컴포넌트
  • Presenter Component: 비즈니스 로직이 없고, 데이터만 뿌려주는 형태의 컴포넌트

Props Drilling Problem

컴포넌트 구조가 복잡해짐에 따라 하위 컴포넌트에 특정 값을 전달하기 위해서는 중간레벨에 있는 컴포넌트는 전부 그 props 를 전달해야 하는 문제가 발생한다.

4. FLUX 패턴과 Redux

FLUX 패턴은 MVC 의 개념에서 벗어나 단방향 아키텍쳐 (uni-directional architecture) 를 추구한다. MVC 의 문제점을 제기했다.

정확히는 MVC 의 문제점이 아니라 기존의 MVC의 경계에 대한 이야기이다. 컴포넌트의 재사용과 독립성을 지나치게 강조하다보니 같은 데이터를 공유하는 과정에서 props를 통해 데이터를 전달하는 문제들로 하여금 Model 의 관리가 파편화 되는 문제가 생김!

View를 하나의 범주로 두고 View 에서 action을 호출하면 Dispatcher를 통해 Store 라는 공간에 Data가 보관되고, 이것이 다시 View로 전달되는 흐름.

Flux 패턴은 다만 Redux만 이해하는데 쓰면 좋다. 실제로 쓰는 패턴이 아니기 때문.

Redux

Flux 패턴을 이용한 구현체인 Redux가 탄생한다.

Flux 패턴은 View 를 각각의 MVC 컴포넌트 관점으로 보는것이 아니라 하나의 큰 View로 이해하고 View 에서는 Dispatch를 통해서 Action을 전달하면 Action 은 Reducer를 통해서 Data가 Store에 보관되고, Store에 들어있는 데이터는 다시 View로 연결되는 방식을 지향한다.

기존의 컴포넌트 단위의 MVC 개념에서 완전히 비즈니스 로직과 View를 분리하며 이 분리된 개념을 상태관리(State Management)라고 부른다.

MVC 에서 FLUX 로 오면서 달라진 점

  • 공통적으로 사용되는 비즈니스 로직의 Layer와 View의 Layer를 완전히 분리하여 상태관리 라는 방식으로 관리한다. 각각의 독립된 컴포넌트가 아니라 하나의 거대한 View영역으로 간주한다. 둘 사이의 관계는 Action 과 Reduce 라는 인터페이스로 분리하며, Controller 는 이제 양방향이 아니라 단방향으로 Cycle을 이루도록 설계한다.

FLUX 패턴의 한계

  • 높은 Learning Curve
  • 심각한 boilerplate

5. 현재 웹프론트엔드의 아키텍쳐 방향성들

Context 와 hook, props 상속

redux의 복잡함이 문제점으로 제기되는 가운데, 좀더 가볍게 쓸 수 있는 API 들이 생겼다.

  • React의 기본기능인 Context API 를 좀 더 사용하는 추세
  • View 와 Model 을 분리

Atomic 패턴 - Recoil, Svelte Store, Vue Composition, jotai

거대한 View 영역과 Store 영역을 나누어 이분법으로 생각하자는 의견에는 동의하나, Action ~ Dispatch ~ Reducer 와 같은 복잡한 구조에 대해 회의적인 시각으로 만들어진 방법.

간단한 문법으로 컴포넌트 외부에서 공통의 데이터를 set, get 을 할 수 있게 하면서 동시에 동기화를 할 수 있는 방향성이다.

개선방향

  • View 와 Model 은 분리
  • 중간의 과정은 자율에 맡기고 간단하게 Model에 접근하는 법만 제공
  • 동기화, 동시성 처리가 중요

React-Query - MVC의 개념 확대

  • 서버와의 fetch 영역을 Model 로 간주
  • View는 React
  • Controller 는 query 와 mutation 이라는 2가지의 인터페이스를 통해서 서버 데이터의 상태를 관리하고 캐싱, 동기화, refetch 등을 관리해주는 역할

redux 에도 rtk-query 라는 매우 비슷한 API 가 있지만, 기존의 복잡함을 덜어내고 라이트하게 만든 것이다.

무마리…

이때까지 무의식중으로 아키텍처를 사용해왔지만, 정확한 의미와 의도를 모른채로 사용해왔다. 역사를 배워보니 어떤 의도와 목적을 가지고 만들어졌는지가 좀 명확해졌다. 앞으로 내가 어떤 방향성을 가지고 아키텍처를 생각해야 되는지 많은 생각이 들었다.

출처

https://towardsdatascience.com/everything-you-need-to-know-about-mvc-architecture-3c827930b4c1

https://velog.io/@teo/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%97%90%EC%84%9C-MV-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94#grahphql-firebase—schema-based-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90

This post is licensed under CC BY 4.0 by the author.

[프론트엔드] 소프트웨어 아키텍처와 디자인패턴(1)

[JS] 자바스크립트의 this