티스토리 뷰

반응형

프로그래밍 알고리즘 패턴은 다양합니다. 다양한 알고리즘 패턴 중 하나인 MVP 패턴에 대해서 알아보겠습니다. 더 나아가 MVC(Model-View-Controller) 패턴과 유사한 MVP을 왜 사용하며 어떻게 사용하는지 나누겠습니다.

MVP 이란?


MVP 은 Model-View-Presenter 로 구성됩니다. MVP가 나오게 된 이유는 View와 Model을 완전한 분리해서 사용하기 위해서 입니다. MVP는 Model의 역할인 비즈니스 로직을 독립적으로 테스트할 수 있습니다. MVP 패턴의 각 구성에 대해서 자세히 알아보겠습니다.

 

MVP 패턴 구성 요소


MVP 모델은 Model-View-Presenter 로 구성됩니다. 

■ 뷰(View)

The view is a passive interface that displays data (the model) and routes user commands (events) to the presenter to act upon that data.
실제 view 에 대한 직접적인 접근을 담당합니다. 안드로이드에서 액티비티/프래그먼트는 뷰의 일부로 정의합니다.  
View 에서 발생하는 이벤트는 직접 핸들링 할 수 있으나 Presenter 에 위임하도록 합니다. 위임하는 방법은 액티비티가 뷰 인터페이스를 구현해서 Presenter에서 코드를 만들 인터페이스를 갖도록 하면 됩니다. 이렇게 하면 특정 뷰와 결합되지 않고 가상 뷰를 구현해서 간단한 유닛 테스트를 실행할 수 있습니다. 

 

■ 프리젠터(Presenter)

The presenter acts upon the model and the view. It retrieves data from repositories (the model), and formats it for display in the view
본질적으로는 MVC의 컨트롤러와 같지만, 뷰에 연결되는 것이 아니라 인터페이스로 연결된다는 점이 다릅니다. 이에 따라 MVC가 가진 테스트 가능성 문제와 함께 모듈화/유연성 문제 역시 해결합니다. 프리젠터(Presenter)의 역할을 한줄로 표현한다면 뷰(View)와 모델(Model) 사이에서 자료 전달 역할을 합니다. 


■ 모델(Model)

The model is an interface defining the data to be displayed or otherwise acted upon in the user interface.
앱 데이터 및 상태에 대한 비지니스 로직을 수행합니다.

* 비즈니스 로직(Business logic)은 컴퓨터 프로그램의 규칙에 따라 데이터를 생성·표시·저장·변경하는 부분을 말합니다. 데이터베이스, 표시장치 등 프로그램의 다른 부분과 대조되는 개념으로 쓰입니다.

 

반응형

 

코드로 보는 MVP (Model-View-Presenter)


간단한 두 수를 더하는 앱을 통하여 MVP 패턴이 어떻게 적용되는지 알아보겠습니다. 앱에서 MVP 패턴의 각 역할은 다음과 같습니다.

뷰(View)
: 액티비티(Activity) 화면 구성 및 인터페이스 제공

프리젠터(Presenter)
: 1. 두 수의 계산 및 데이터를 저장합니다. 2.모델에 데이터를 전송하여 저장하는데 도움을 줍니다.

모델(Model)
 : 데이터를 저장합니다

 

 

뷰(View)

Presenter에서 호출 할 수 있도록 View의 Interface을 갖고 있으며, Presenter을 생성하여 Interface로 View와 Presenter 통신 합니다. 또한위젯 조작을 구성하고 있습니다.

public class MainActivity extents Activity implements MainConstants.View {   MainConstants.Presenter mainPresenter;​  @Override  public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                mainPresenter = new MainPresenter();                initListener();    }       private void initListener(){       String inputA = ((EditText)findViewById(R.id.editInputA)).getString().toString();       String inputB = ((EditText)findViewById(R.id.editInputB)).getString().toString();       // '=' 버튼 클릭 시 덧셈 결과 받기       findViewById(R.id.btnResult).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                mainPresenter.addNums(inputA, inputB);            }        });   } ​   @Override   public void showResult(int result){      ((TextView)findViewById(R.id.txtResult)).setText(Integer.toString(result));   }}

 

 


프리젠터(Presenter)

View 의 통신을 위해서 Interface을 갖고 있으며, Model을 직접적으로 연결합니다. Presenter에서 UI 작업은 View의 Interface을 통해서 표시 합니다. 데이터 저장, 삽입, 등 비즈니스 로직이 필요 시 Model을 호출하여 작업합니다.

 

public interface MainConstants {    interface View{        // View 에 계산한 결과를 표시        void showResult(int result);    }​    interface Presenter{        // View에서 입력한 두 수에 대한 덧셈        void addNums(int input1, int input2);​        // 데이터 저장        void saveData(int data);    }}

 

public class MainPresenter implements MainConstants.Presenter {    MainConstants.View mainView;    MainModel mainModel;​    public MainPresenter(MainConstants.View view){        // View 연결        mainView = view;​        // Model 연결        mainModel = new MainModel(this);    }​​    @Override    public void addNums(int input1, int input2) {        mainView.showResult(input1 + input2);    }​    @Override    public void saveData(int data) {        mainModel.saveData(data);    }}


모델

비즈니스 로직만 구성됩니다. Presenter에 저장된 데이터를 호출하여 전송 및 데이터를 저장하는 기능을 하게 됩니다.

 

public class MainModel {    MainConstants.Presenter presenter;    public MainModel(MainConstants.Presenter presenter){        this.presenter = presenter;    }​    // Presenter 에서 데이터 저장 시 호출됩니다    // 자세한 저장 로직은 생략했습니다    public void saveData(int data){        //Todo..SaveData    }}

 

 

정리


앱 프로젝트 진행하다보면 소스 정리에 대해 고민을 하게 되는데, MVP 패턴을 사용한다면 인터페이스와 로직을 분리해서 관리 할 수 있다는 장점이 있습니다. 또한 유닛테스트로 활용 시 테스트 화면만 그려서 테스트 할 수 있다는 장점이 있었습니다. 단점으로는 하나의 화면을 생성 시 View, Model, Presenter, Interface 를 생성해야하는 불편함이 있습니다. 또한 프로젝트가 커질 수록 Presenter의 자원이 많아질 수 있습니다. 패턴으로 코드의 가독성 및 유지보수에 도움을 줄 수 있으나 프로젝트에 따른 코드 자원의 증가를 어떻게 관리 할 것인지 연구가 필요해 보입니다.

 

참고

 


https://github.com/googlesamples/android-architecture/tree/todo-mvp/

https://academy.realm.io/kr/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter

 

 

 

반응형
댓글