디자인 패턴 - MVC, MVP, MVVM 구조

이우건·2023년 12월 17일
0

안드로이드

목록 보기
8/20

MVC

MVC 디자인 패턴은 하나의 어플리케이션을 Model + View + Controller로 이루어진 3개의 측면으로 분리하여 개발하는 디자인 패턴이다.

동작

  1. 사용자의 Action들은 Controller로 들어오게 된다.
  2. Controller는 사용자의 Action을 확인하고, Model을 업데이트한다.
  3. Controller는 Model을 나타내줄 View를 선택한다.
  4. View는 Model을 이용하여 화면을 나타낸다.

MVC에서 View가 업데이트 되는 방법

  • View가 Model을 이용하여 직접 업데이트 하는 방법
  • Model에서 View에게 Notify하여 업데이트 하는 방법
  • View가 Polling으로 주기적으로 Model의 변경을 감지하여 업데이트 하는 방법

특징

Controller는 여러 개의 View를 선택할 수 있는 1:n 구조이다.
Controller는 View를 선택할 뿐 직접 업데이트 하지 않는다. (View는 Controller를 알지 못한다.)

Model

Model은 View에 표시되기 위해 필요한 데이터이다. Model은 비즈니스 로직을 설명하는 클래스의 집합으로 구성된다. Model은 어떻게 데이터가 변경되고 조작될 수 있는지에 관한 규칙을 정의한다.

View

View는 안드로이드의 XML, 프론트엔드의 HTML과 같은 UI 구성요소를 나타낸다. View는 Controller로 부터 받은 UI 데이터를 표시하는 역할을 한다. MVC 패턴에서의 View는 옵저버 패턴을 이용하여 Model을 관찰하게 된다. 이는 데이터의 상태 변화를 업데이트 하기 위함이다.

Controller

Controller는 다가오는 사용자의 요청을 처리하는 역할을 담당하고 있다. Controller는 Model을 통해 받은 데이터를 처리하거나, 결과 값을 View에 반환하는 역할을 한다.

장점

가장 단순한 패턴으로 여러 개발 분야에서 보편적으로 사용되는 디자인 패턴이다.

단점

View와 Model사이의 의존성이 높다. 이는 어플리케이션이 커질수록 유지보수가 어려워진다.

MVP

MVP 패턴은 MVC와 유사한 디자인 패턴이다. 기존 Controller의 역할을 Presenter가 한다고 보면 된다.

동작

  1. 사용자의 Action은 View를 통해 들어오게 된다.
  2. View는 데이터를 Presenter에 요청한다.
  3. Presenter는 Model에게 데이터를 요청한다.
  4. Model은 Presenter에게 요청받은 데이터를 응답한다.
  5. Presenter가 데이터를 가공하고 다시 View에게 응답한다.
  6. View는 Presenter로부터 데이터를 응답받고 UI 데이터를 갱신한다.

Model

어플리케이션에서 사용되는 데이터와 그 데이터를 처리하는 부분이다.

View

사용자에게 보여지는 UI 부분이다.

Presenter

Presenter는 interface를 통하여 View와 상호작용한다. interface는 필요한 데이터를 전달하느 ㄴpresenter 클래스에서 정의된다. 안드로이드의 경우 액티비티나 프래그먼트와 같은 view 구성요소는 이 인터페이스를 구현하고 원하는 방식으로 데이터를 렌더링한다.

MVP 패턴에서 Presenter는 Model을 조작할 뿐만 아니라 View를 업데이트 한다. Presenter와 View는 서로 완전히 분리되어 인터페이스를 통해 통신한다.

안드로이드에서의 presenter

Contract interface

interface MovieContract {
    interface View {
        fun showProgress()
        fun hideProgress()

        fun changeMovieList(movies: List<MovieEntity>)
        fun showToast(text: String)
    }

    interface Model {
        interface OnFinishedListener {
            fun onFinished(movies: List<MovieEntity>)
        }

        fun getMovies(movie: MovieResponse, onFinishedListener: OnFinishedListener?)
    }

    interface Presenter {
        fun searchButtonClick(inputText: String)
        fun apiError()

        fun itemClick(movie: MovieEntity)
    }
}

출처: https://heegs.tistory.com/114 [Heeg's Log:티스토리]

MoviePresenter class

class MoviePresenter(
    private val userApi: ApiInterface,
    private val networkManager: NetworkManager,
    private var activity: MovieContract.View?,
    private var model: MovieContract.Model,
) : MovieContract.Presenter, MovieContract.Model.OnFinishedListener {


    override fun searchButtonClick(inputText: String) {
        CoroutineScope(Dispatchers.Main).launch {
            ...
            if (!networkManager.checkNetworkState()) {
                apiError()
            } else {
                try {
                    model.getMovies(userApi.getSearchMovieFlow(input), this@MoviePresenter)
                } catch (e: Exception) {
                    apiError()
                }
            }
        }
    }

    ...

    override fun onFinished(movies: List<MovieEntity>) {
        activity!!.hideProgress()
        if (movies.isEmpty()) {
            activity!!.showToast("Movie list is Empty")
        }

        activity!!.changeMovieList(movies)
    }
}

출처: https://heegs.tistory.com/114 [Heeg's Log:티스토리]

위 주소의 작성자분 샘플 코드를 참조하였다.

MVVM

MVVM 패턴은 양방향 데이터 바인딩을 지원한다. 이에 따라 View Model 안에 있는 데이터의 변화를 View에 전파한다. (옵저버 패턴) 일반적으로 옵저버 패턴을 활용하여 View Model의 변경사항을 Model에게 알린다.

동작

  1. 사용자의 Action들은 View를 통해 들어온다.
  2. View에 Action이 들어오면 ViewModel에 Action을 전달한다.
  3. ViewModel은 Model에게 데이터를 요청한다.
  4. Model은 ViewModel에게 요청받은 데이터를 응답한다.
  5. ViewModel은 응답 받은 데이터를 가공하여 저장한다.
  6. View는 Data Binding을 이용해 UI을 갱신시킨다.

ViewModel

viewModel은 View 상태를 유지 및 변화시키고, View에 대한 작업의 결과로 Model을 조작하고, View에서 발생되는 이벤트를 트리거하는데 도움이 되는 메서드, command 또는 다른 속성들을 노출하는 역할을 한다.

View는 ViewModel에 관한 참조를 가지고 있지만, ViewModel은 View에 관한 정보를 모른다. 이는 View와 ViewModel사이의 n:1의 의존관계가 생기며 다수의 View는 하나의 ViewModel에 매핑될 수 있다. 이로써 ViewModel은 다수의 View에 대해 완전히 독립적이다.

참조

profile
머리가 나쁘면 기록이라도 잘하자

0개의 댓글