대가는 결과를 만든다

디자인 패턴에 대해 정리해보자 : MVC, MVP, MVVM, Flux 본문

개발/디자인 패턴

디자인 패턴에 대해 정리해보자 : MVC, MVP, MVVM, Flux

yunzema 2019. 6. 14. 08:46
반응형

1. 디자인 패턴?

- 설계 규칙이라고 이해하면 무방하다. 프로그래밍을 할 때 기본적으로 '사용자의 인터렉션 -> 로직 -> data의 변화 -> 사용자에게 보이는 UI의 변화'로 흘러간다. 이 흐름을 구현할 때 설계를 규칙화한다면, 수정과 유지보수에 유리하기 때문에 디자인 패턴의 필요하다.

- 디자인 패턴은 여러가지가 있으며 각 패턴마다 장단점이 있을 수 있고, 상황과 언어 프레임워크에 따라 그 장단점이 다를 수 있겠다.

 

* 의존성(Dependency)이란?

자주 등장하게 되는 용어 의존성의 개념에 대해 정리해보자 : 두 모듈간의 연결, 두 클래간의 관계, 둘중 하나가 다른 하나를 사용하는 상황을 의존성이 생긴다라고 할 수 있겠다. 좀더 단순히 말하면, 파라미터나 리턴값 또는 지역변수 등으로 다른 객체를 참조하는 것!

의존성은 최소화되어야 한다. 그 이유는 의존성이 있는 코드는 변경이 또 다른 곳에 변경을 전파되는 의존성 전이가 발생하기 때문이다.

예측가능성이 떨어지고, 코드의 수정이 불안정해진다.

의존성에 대해 잘 정리한 글 참고 (컴파일타임 의존성, 런타임 의존성) : https://mangkyu.tistory.com/226

 

2. MVC

 

- 구성 요소 : Model, View, Controller

- 이 3가지 구성요소들을의 역할을 아래의 가이드라인에 따라 분담한다.

  => 작성하는 코드가 여기에 있는게 맞는지? 이 데이터를 여기서 참조하는게 규칙에 어긋나지 않는지? 에 대해 고민하고 점검해야 한다!

 

- 1. Model : 데이터 자체나 데이터 가공을 책임지는 요소

   - 사용자가 편집하길 원하는 모든 데이터를 보유한다.

   - View, Controller에 대해 어떤 정보도 참조하면 안된다.

   - Model의 변경에 대해 통지, 처리에 대해 구현해야 한다. 변경을 외부로 알리거나, 변경을 수신한다.

   - 재사용이 가능해야 한다.

 

- 2. View: 사용자 인터페이스 요소로, 입력/출력의 역할을 담당하는 사용자가 볼 수 있는 화면 요소

  - 모델이 가지고 있는 정보를 따로 저장하지 않는다.

  - Model, Controller에 대해 참조하거나 알지 않는다. 데이터를 받으면 화면에 표시만 하는 역할을 한다.

  - 변경이 일어나면 모델에게 변경 통지를 구현해야 한다. 변경을 외부로 알리거나, 변경을 수신한다.

  - 재사용이 가능해야 한다.

 

- 3. Controller : Model과 View를 잇는 다리역할을 한다. View, Model의 변경 이벤트들을 처리한다.

  - Model, View에 대해 알고 있어야 한다.

  - Model, View의 변경을 관찰하고 있다가 통지를 받으면, 각 구성요소에게 통지를 한다.

  - 여러 View가 연결될 수 있다.

  - 메인 로직은 컨트롤러가 담당한다.

 

=> Model 데이터처리, View 사용자가 보는 페이지, Controller 이 2가지를 중간에서 제어하는 컨트롤 , 이 3가지로 구성되는 하나의 애플리케이션을 만들면 각각 맡은바에만 집중할 수 있다. 유지보수성, 확장성, 유연성을 높인다.

 

=> 하지만 기능이 추가될 수록 Controller의 규모가 커지며 복잡도가 커진다 : Massive ViewController (대규모 MVC 어플리케이션) 

  - * Controller를 통해 View와 연결되는 Model이 여러개로 늘어나면 view와 model이 서로 의존성을 띄게된다.

  - View와 Model 사이의 데이터 복잡도, Model들간의 종속 업데이트로 개발이 어려워진다.

    - 한 Model이 업데이트되면 그에 따라 View가 업데이트되고, 업데이트된 View가 또 다른 Model을 업데이트하는 식의 복잡한 데이터 흐름을 가지게 된다. 이렇게 많은 의존성을 가지면 Model의 개수가 많아질수록 각 Model에서 발생한 이벤트가 애플리케이션 전체로 퍼져나갈 때 이를 예측하기 힘들어 진다.

  => 위 문제점을 해결하기 위해 아래에 설명하게 될 패턴들을 파생시키게 되었다 : MVP, MVVM, Flux 등..

 

- 참고 : https://medium.com/@jang.wangsu/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-mvc-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80-1d74fac6e256

 

3. MVP

- 구성요소 : Model, View, Presenter

- Model과 View는 동일!

- Presenter

  - View와 Model의 인스턴스를 가지고 둘을 연결하는 역할을 한다.

  - Presenter와 View는 1:1 관계

 

- 동작흐름

  1. 사용자의 Action이 View를 통해 들어옴
  2. View는 데이터를 Presenter에 요청
  3. Presenter는 Model에게 데이터를 요청
  4. Model은 Presenter에서 요청받은 데이터를 응답
  5. Presenter는 View에게 데이터를 응답
  6. View는 Presenter가 응답한 데이터를 이용하여 화면을 표현

- MVC의 단점을 개선한 형태로 View와 Model 사이의 의존성이 없다. Presenter를 통해서만 데이터를 전달한다.

- 하지만 View와 Presenter 사이의 의존성이 강해진다는 단점이 생긴다.

 

 

4. MVVM

- 구성요소 : Model, View, View Model

- 비즈니스(데이터) 로직과 프레젠테이션(화면) 로직을 분리한다.

- MVC의 단점을 개선한 형태로 View와 Model 사이의 의존성이 없음

- View와 View-Model 사이의 의존성은 Command패턴과 Data Binding을 이용해 없앤다.

 

- 1. Model : 애플리케이션에서 사용되는 데이터와 해당 데이터를 처리

- 2. View : UI 구성 요소. 모델을 UI로 변경

  - 여러 View-Model이 연결될 수 있음

  - View-Model에 대한 참조가 존재할 수 있음

- 3. View-Model: 뷰에 필요한 데이터를 모델에 요청하고, 응답받은 데이터를 가공하여 뷰에 전달

 

- Vue

  - Vue가 대표적으로 View-Model 역할을 수행하는 프레임워크

  • 모델(Model) : 데이터이며, 데이터 변경할 경우 Vue인스턴스에 변경을 알리며(뷰모델에 command패턴으로 action을 전달) vue의 getter/setters로 객체의 프로퍼티를 변환됩니다. 
  • 뷰(View) : UI요소이며, 뷰모델에 의해 관리됩니다. 뷰 요소는 vm.$el로 설정되어 Vue 인스턴스 생성당시에 컴파일되어 뷰모델의 데이터, 메서드등이 Binding 됩니다.
  • 뷰모델(View) : Vue 인스턴스는 뷰모델이며 뷰에 필요한 기능, 필드을 갖고 모델과 뷰를 연결하는 역할을 수행합니다.

  - * 그럼 react는? : react는 view단에 해당하는 ui 라이브러리이고, react만 가지고 mvvm 패턴으로 직접 구현하는 것은 비효율적이다. 아래에서 설명하는 Flux, Redux패턴을 참고하자!

 

- 동작 흐름

   1. 사용자의 Action이 뷰를 통해 들어옴

   2. 뷰에서 Action이 들어오면, Command 패턴으로 뷰모델에 Action을 전달

   3. 뷰모델은 모델에게 데이터를 전달

   4. 모델은 뷰모델에게 요청 받은 데이터를 응답

   5. 뷰모델은 응답 받은 데이터를 가공하여 저장

   6. 뷰는 뷰모델과 Data binding으로 화면을 나타냄

 

 

4. Flux

- MVC 패턴이 스케일업 되면 V와 M사이 데이터 복잡도와, M들간의 종속 업데이트로 인해 수정에 대한 예측가능성이 떨어진다는 단점을 극복하기 위해 페이스북에서 Flux 패턴을 만들었다.

- 사용자의 입력을 기반으로 Action을 만들고, Action을 Dispatcher에 전달하여 Model(store)의 데이터를 변경한 뒤 View에 반영하는 단방향의 흐름으로 애플리케이션을 만든다.

 

 

- 구성요소 : Action, Dispatcher, Model, View

- Action : 데이터를 변경하는 행위로서 Dispatcher에게 전달되는 객체를 말한다. type과 payload(data)를 묶어 dispatcher에 전달한다.

{
  type: 'SET_USER_INFO',
  data: {
    name: 'Sam',
    age: 13
  }
}

- Dispatcher : 모든 데이터의 흐름을 관리하는 중앙 허브이다. Action 타입마다 콜백함수들이 존재해서 해당 Action을 감지하면 store(model)이 각 타입에 맞는 store(model)의 콜백함수를 실행한다. 

  - store(model)의 데이터 조작은 dispatcher를 통해서만 가능하다. store(model)들 사이에 의존성이 ㅅ는 상황에도 순서에 맞게 콜백함수를 순차적으로 처리하도록 한다.

 

- Store(Model) : 상태와 상태를 변경할 수 있는 메서드를 가지고 있다. 어떤 타입의 Action이 발생했는지에 따라 그에 맞는 데이터 변경을 수행하는 콜백함수를 Dispatcher에 등록한다. Dispatcher에서 콜백함수를 실행하여 상태가 변경되면 View에게 데이터 업데이트가 되었음을 알린다.

 

- View : 리엑트 컴포넌트. Store(Model)에서 상태가 업데이트 되었다는 것을 인지하면, 최상위 View에 해당하는 컴포넌트는 store에서 데이터를 가져와 자식 컴포넌트에게 내려보낸다. 새로운 데이터를 받은 컴포넌트는 화면을 리렌더링한다.

 

 

 

'개발 > 디자인 패턴' 카테고리의 다른 글

adapter 패턴  (0) 2023.02.12
Comments