MVP Pattern


MVP 패턴의 동작
- 1. View에서 사용자의 이벤트 수신
- 2. View에서 Presenter 이벤트 호출
- 3. Presenter에서 Model에 데이터 요청
- 4. Model에서 Presenter로 데이터 전달
- 5. Presenter에서 전달받은 데이터를 기반으로 View 업데이트
- 6. View에서 화면 업데이트
- Model
내부적으로 쓰이는 데이터를 저장하고, 처리하는 역할을 한다. 흔히 ‘Business Logic’ 이라고 부르는 부분이다. View, Presenter 등 다른 어떤 요소에도 의존적이지 않은 독립적인 영역이다.
1
2
3
4
5
6
7
8
9
10
11
public class ResultUrl {
    private String message;
    private String code;
    private ResultFormat result;
    public ResultUrl(String message, String code, ResultFormat result) {
        this.message = message;
        this.code = code;
        this.result = result;
    }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class GetServerResponseImpl implements MainContractor.GetServerResponse {
    @Override
    public void getNoticeURL(final OnFinishedListener onFinishedListener, String url) {
        RetrofitService retrofit = RetrofitInstance.getRetrofitInstance().create(RetrofitService.class);
        retrofit.sendShortURL(url).enqueue(new Callback<ResultUrl>() {
            @Override
            public void onResponse(Call<ResultUrl> call, Response<ResultUrl> response) {
                if (response.isSuccessful()){
                    if (response.body() != null){
                        onFinishedListener.onFinished(response.body().getResult().getUrl());
                        Log.e("result url",""+response.body().getResult().getUrl());
                    }
                }
            }
            @Override
            public void onFailure(Call<ResultUrl> call, Throwable t) {
                onFinishedListener.onFailure(t);
                Log.e("shotURL Failure",""+t.toString());
            }
        });
    }
}
- View
실제 View 에 대한 직접적인 접근을 담당한다. 안드로이드에서 Activity/Fragment 는 View의 일부로 정의한다. View의 일부로 정의한다. View 에서 발생하는 이벤트는 직접 핸들링 할 수 있으나 Presenter 에 위임하도록 한다. 위임하는 방법은 Activity 가 View Interface 를 구현해서 Presenter 에서 코드를 만들 인터페이스를 갖도록 하면 된다. 이를 통해 특정 뷰와 결합되지 않고 가상 뷰를 구현해서 간단한 유닛 테스트를 실행할 수 있다.
1
2
3
4
5
6
7
8
9
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    mainPresenter = new MainPresenter(this, new GetServerResponseImpl());
    mainPresenter.attachView(this);
}
- Presenter
본질적으로는 MVC의 컨트롤러와 같지만, 뷰에 연결되는 것이 아니라 Interface로 연결된다는 점이 다르다. 이에 따라 MVC가 가진 테스트 가능성 문제와 함께 모듈화/유연성 문제 역시 해결한다. Presenter의 역할을 정의한다면 View 와 Model 사이에서 자료 전달 역할을 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public interface MainContractor {
    interface View {
        void showResult();
        void setResultURL(String url);
    }
    interface Presenter {
        void attachView(View view);
        void detachView();
        void loadURL(Context context, String url);
    }
    interface GetServerResponse {
        interface OnFinishedListener {
            void onFinished(String resultURL);
            void onFailure(Throwable t);
        }
        void getNoticeURL(OnFinishedListener onFinishedListener, String url);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MainPresenter implements MainContractor.Presenter, MainContractor.GetServerResponse.OnFinishedListener{
    private MainContractor.View view;
    private MainContractor.GetServerResponse getNoticeIntractor;
    public MainPresenter(MainContractor.View view, MainContractor.GetServerResponse getNoticeIntractor) {
        this.view = view;
        this.getNoticeIntractor = getNoticeIntractor;
    }
    @Override
    public void attachView(MainContractor.View view) {
        this.view = view;
    }
    @Override
    public void detachView() {view = null;}
    @Override
    public void loadURL(Context context, String url) {
        getNoticeIntractor.getNoticeURL(this,url);
    }
    @Override
    public void onFinished(String resultURL) {
        view.setResultURL(resultURL);
    }
    @Override
    public void onFailure(Throwable t) {
        Log.e("network onFailure",""+t.toString());
    }
}
MVC와 MVP의 차이
MVC 는 Model-View-Controller 로 코드를 구성하는 디자인 패턴이다.
Model과 View는 MVC,MVP가 역할이 같지만 Controller와 Presenter는 약간 다르다.
MVC에서는 사용자의 이벤트에 Controller가 먼저 반응한 후 View를 가져와 적절한 작업 후 반환한다.
MVP에서는 사용자의 이벤트에 View가 먼저 반응한 후 Presenter에 알리고 작업을 처리한 후 View한테 다시 알려준다.
왜 사용할까?
MVP와 같은 디자인 패턴은 앱을 구성하는 코드를 모듈화시킬 수 있다. 협업 시 각각 전문분야에서만 작업을 해도 된다. 소스파일을 관리하기 더 편해지고 유닛 테스트에 용이해진다는 장점이 있다. 즉, 전체적인 유지보수가 쉬워진다.
