MVVM 디자인패턴

Danbi Cho·2020년 5월 31일
1

디자인 패턴

  • 디자인 패턴이란 소프트웨어 공학론에서 좋은 코드를 설계하기 위한 일종의 설계 디자인 방법론을 말한다.

좋은 코드란 간결한 코드, 가독성이 좋은 코드 등 여러 가지가 있지만, 디자인 패턴에서는 설계적 관점에서의 좋은 코드를 말한다. 또한, 확장과 수정이 용이하고 설계 이후에도 추가적인 유지 보수에 비용이 적게 들어가는 코드를 말한다.

  • 여러가지 디자인 패턴 중 가장 많이 알고 있는 디자인 패턴에는 크게 3가지가 있다.

MVC (Model - View - Controller)

  • Controller에 직접 Input
  • View와 Controller: Many to One 관계
  • View는 Controller를 참조하지 않음
  • Model은 View를 간접적으로 참조
    아키텍처 최상위에 View가 있고, 그 아래 Controller, 그 아래 Model이 있는 형태.
    때문에 View는 Controller만 알고 있고, Controller는 Model을 알고 있다. Model이 변경되었을 때 뷰는 Controller를 통해서 변화를 전달받는다.

MVP (Model - View - Presenter)

  • View에 직접 Input
  • View와 Presenter: One to One 관계
  • View는 자신의 Presenter를 참조하고 Presenter 역시 View를 알고 있음
  • View는 Model을 참조하지 않아 Presenter를 통해 Model을 업데이트 함
    MVC 패턴에서 Controller가 Presenter로 교체된 형태, Presenter는 View와 같은 레벨에 존재.
    Presenter는 View와 Model의 이벤트를 모두 받고, 둘 사이의 상호작용을 조정한다.

MVVM (Model - View - ViewModel)

  • View에 직접 Input
  • View와 ViewModel: Many to One 관계
  • ViewModel은 View를 참조하지 않음
  • View는 Model을 참조하지 않아 ViewModel을 통해 Model을 업데이트함
    MVC 패턴에서 Controller가 ViewModel로 교체된 형태, ViewModel은 UI 레이어 아래에 위치.
    ViewModel은 View가 필요로 하는 데이터와 커맨드 객체를 노출해 주기 때문에 View가 필요로 하는 데이터와 액션은 담고 있는 컨테이너 객체로 볼 수도 있다.

MVVM 패턴

MVVM 패턴의 목표는 비즈니스 로직과 프레젠테이션 로직을 UI로부터 분리하는 것이다.
비즈니스 로직과 프레젠테이션 로직을 UI로부터 분리하면 유지 보수, 재사용, 테스트가 쉬워진다.

  • 데이터 모델(Model)
  • 화면을 보여주는 뷰(View)
  • 뷰에서 발생되는 이벤트 행동들을 뷰 모델(VeiwModel)
    3가지 요소로 구성되어 있다.

뷰(View)

  • 뷰의 역할은 UI에 관련된 것을 다루는 것이다. 사용자가 화면을 통해 보는 레이아웃, 구조를 정의한다. 뷰는 애니메이션 같은 UI 로직을 포함하되 비즈니스 로직을 포함하지 않아야 한다.

뷰 모델(VeiwModel)

  • 뷰 모델의 역할은 뷰가 사용할 메서드와 필드를 구현하고, 뷰에 상태 변화를 알리는 것이다. (뷰는 모델의 상태 변화를 옵저빙 한다.) 뷰 모델에서 제공하는 메서드와 필드가 UI에서 제공할 기능을 정의하고, 뷰가 이 기능을 어떻게 보여줄 것인지 결정한다.

  • 뷰 모델과 모델은 일반적으로 One to Many의 관계를 형성한다. 뷰 모델은 뷰가 사용하기 쉽도록 모델의 데이터를 가공하여 뷰에게 제공한다. 뷰에서 서로 다른 두 모델의 데이터를 활용한 데이터가 필요하다면, 뷰에서 모델의 값을 조작하여 사용하는 것이 아니라 뷰 모델에서 두 모델의 데이터를 가공하고 뷰에서는 UI만 보이도록 한다.

모델(Model)

  • 모델은 비즈니스 로직과 데이터를 포함하는 도메인 모델로 생각할 수 있다. 즉, 모델은 사용할 데이터에 관련된 동작과 데이터를 다룬다.

장점

  • 뷰 모델이 모델과 뷰 사이의 어댑터 역할을 하기 때문에 변화가 생겼을 때 수정을 최소화할 수 있다.
  • 모델과 뷰 모델이 뷰로부터 독립적이다.
    • 뷰 모델과 모델을 플랫폼에서 독립적인 형태로 개발할 수 있다.
    • UI 디자인이 나오지 않은 상태에서도 미리 정의된 모델과 뷰 모델을 개발할 수 있기 때문에 병렬적인 개발이 가능하다.
    • 테스트가 용이하다.

단점

  • 이렇게 디자인 패턴을 적용하여 개발하는 것은 큰 프로젝트를 진행할 때를 고안하여 만들어진 것이기 때문에 작은 프로젝트에서는 적합하지 않다. (오버헤드 발생)
  • 프로젝트가 커지면 데이터 바인딩 때문에 메모리 소모가 많아진다.

프로젝트 관력 기록
1. domain/entity 폴더 안에 설정해 주었던 OrerList에 대한 Promise 객체를 interface로 export 하여 사용한다.

export interface OrderList {
  list: Promise<OrderList>;
}
  1. OrderList를 usecase에서 가져온다.
import { inject, injectable } from "inversify";
import { GetOrderList } from "domain/use-case";
import { OrderListRepository } from "domain/interactor/repository";

@injectable()
export default class GetOrderListImple implements GetOrderList {
  private orderListRepository: OrderListRepository;

  constructor(
    @inject("OrderListRepository")
    orderListRepository: OrderListRepository
  ) {
    this.orderListRepository = orderListRepository;
  }

  execute(email: string) {
    return this.orderListRepository.getOrderList(email);
  }
}
  1. data/api/index.d.ts에서 데이터를 가져온다.
export interfase OrderApi {
	getOrderList(): 
}
  • API -> Repo -> Domain(entity/usecase) -> ViewModel -> View의 파일 구조로 이루어진 프로젝트
    ViewModel이 보여지는 페이지 단위를 말한다.
    Veiw가 컴포넌트를 말한다 -> 우리가 아는 그 컴포넌트
    inject()에 있는 것 inject.tx 안에 있는 것을 꺼내 오기 때문에 Api 이름을 똑같이 쓰는 것이 좋다.
    바로 가져 오면 바깥 레이어의 내용을 아는 것이 되기 때문에 injector에 넣어 놓을 것을 가져 오는 것이다.
  1. container에 어떤 것을 만들었는지 적어준다 . 만든 구현체를 어떤 이름으로 할 것인지.
    domain/entity/index.d.ts
    entity를 export interface 해준다.
export interface Request {
  id: number;
  name: string;
  src: string;
  cost: number;
}

usecase/index.d.ts
export interface 해준다. 인자가 없으면 execute()로만 해주면 된다.
import에도 추가 해줘야 한다.

이렇게 MVVM 디자인 패턴 이론에 대해 공부하고, 실제 기업 협업을 하는 프로젝트에서 적용하면서 더 이해하도록 노력해야 할 것 같다.

profile
룰루랄라! 개발자 되고 싶어요🙈

0개의 댓글