학습 노트: Android 의 MVC 모드 와 MVP 모드

한 프로젝트 가 시작 되 기 전에 개발 자 는 프로젝트 의 크기 와 내용 에 따라 어떤 디자인 모델 과 구 조 를 사용 할 지 결정 하고 적당 한 디자인 모델 을 선택 하면 프로젝트 개발 분업 을 더욱 명확 하고 효율 적 이 며 오류 율 이 낮 으 며 유지 가 더욱 쉽다.내 가 보기에 디자인 모델 은 하나의 프로젝트 의 코드 를 여러 개의 작은 블록 으로 나 누 어 모든 작은 블록 의 결합 성 을 최대한 낮 추고 모든 모듈 의 코드 를 재 활용 성 을 강화 하여 프로젝트 의 유 지 를 더욱 간단 하 게 하 는 방법 이다.다음은 MVC 모델 과 그의 개선 모델 인 MVP 모델 을 배 워 보 겠 습 니 다. 이 두 모델 에 대해 저 는 인터넷 에서 많은 자 료 를 봤 습 니 다. 많은 사람들 이 이 두 모델 에 대해 대체적으로 같은 견 해 를 가지 지만 세부 적 인 차이 가 매우 큽 니 다. 저 는 그들의 프로젝트 경험 과 관련 이 있 고 다음은 제 가 정리 한 의견 이 라 고 생각 합 니 다.
MVC 모드
MVC 의 전체 이름 은 Model View Controller 로 모델 (model) - 보기 (view) - 컨트롤 러 (contrller) 의 줄 임 말 입 니 다. 업무 논리, 데이터, 인터페이스 로 분 리 된 방법 으로 코드 를 구성 하고 업무 논 리 를 한 위 젯 에 모 으 며 개성 화 된 맞 춤 형 인터페이스 와 사용자 의 상호작용 을 개선 하 는 동시에 업무 논 리 를 다시 작성 할 필요 가 없습니다.이것 은 일종 의 소프트웨어 디자인 모델 로 안 드 로 이 드 개발 에 만 응용 되 는 것 이 아니 라 모든 소프트웨어 디자인 에 이런 모델 이 있다.그 중에서 M 층 안에 데이터베이스 액세스 작업, 네트워크 작업, 복잡 한 알고리즘, 시간 소모 작업 등 이 모두 model 층 에 있 습 니 다.V 층 처리 인터페이스의 표시 결과 XML 레이아웃 은 V 층 으로 볼 수 있 습 니 다.C 층 은 교량 역할 을 하 는데, 일반 액 티 비 티 는 컨트롤 러, 액 티 비 티 는 V 그래 픽 의 데 이 터 를 읽 고 사용자 의 입력 을 제어 하 며 모델 에 데이터 요청 을 보낸다.그러나 안 드 로 이 드 개발 에 서 는 이 3 층 구 조 를 분명하게 분리 할 수 없 으 며, Activity 는 MVC 모델 에서 View 층 과 C 층 의 역할 을 병행 하고 있다.  
MVC 장점:
  • 프로젝트 모듈 코드 간 의 결합 성 을 낮 춘 다.
  • 프로젝트 를 확장 성과 유지 보수 성 이 좋 습 니 다
  • MVC 단점:
  • 프로젝트 가 클 수록 UI 가 복잡 해 지고 Model 층 과 View 층 이 상호작용 을 하기 때문에 Activity 가 점점 복잡 해 지고 검사 와 유지 가 매우 번 거 로 워 집 니 다.

  • 2. MVP 모드
    UI 생 성 기술 의 기능 이 날로 강화 되면 서 UI 층 도 점점 더 많은 직책 을 수행 하고 있다.보기 (View) 와 모델 (Model) 의 기능 을 더욱 세분 화하 기 위해 View 는 데이터 의 시각 화 및 사용자 와 의 상호작용 에 집중 하고 Model 은 데이터 의 처리 와 만 관계 하도록 하기 위해 MVC 개념 을 바탕 으로 하 는 MVP (Model - View - Presenter) 모델 이 생 겨 났 다.MVP 모드 는 전형 적 인 MVC 모드 에서 변 화 된 것 으로 MVC 에서 Controller 를 Activity 에서 꺼 내 Activity 의 코드 를 UI 인터페이스의 제어 에 집중 시 킨 다음 에 View 와 Model 의 관 계 를 끊 고 꺼 낸 일부분 은 새로운 이름 Presenter 에 게 View 와 Model 을 연결 하 는 데 사용 했다.
    MVP 장점
  • Model 층 과 View 층 의 관 계 를 완전히 차단 하여 프로젝트 모듈 간 의 결합 성 을 더욱 낮 추 었 다. Model 모듈 을 쓴 사람과 UI 모듈 을 하 는 사람 은 상대방 이 무슨 생각 을 하 는 지 전혀 신경 쓰 지 않 아 도 된다.
  • 단원 테스트 를 편리 하 게 진행 할 수 있 고 Presenter 에서 테스트 코드 를 편리 하 게 쓸 수 있 으 며 정식 코드 와 테스트 코드 가 섞 여 혼 란 스 럽 게 하지 않 아 도 된다.
  • Activity 의 메모리 유출 을 최대한 피 할 수 있 습 니 다. APP 의 메모리 가 부족 할 때 시스템 은 백 엔 드 에 있 는 Activity 의 자원 을 자동 으로 회수 합 니 다. 전통 적 인 MVC 모드 에서 비동기 작업 과 UI 에 대한 작업 이 모두 Activity 에 놓 여 있 습 니 다. 비동기 작업 의 스 레 드 대상 등 은 Activity 가 끝 난 후에 끝나 지 않 을 수 있 습 니 다.Activity 인 스 턴 스 에 대한 인용 을 유지 하기 때문에 시스템 은 이 Activity 인 스 턴 스 를 회수 할 수 없습니다. 결 과 는 Activity 의 메모리 유출 입 니 다. MVP 모드 에서 필요 한 비동기 작업 을 모두 modle 층 에 두 기 때문에 현재 Activity 의 onDestroy 에서 Presenter 층 에 대한 인용 을 해제 하면 메모리 유출 을 편리 하 게 피 할 수 있 습 니 다.

  • MVP 단점
  • 이 를 응용 하려 면 추가 적 인 학습 지식 과 코드 구조 가 필요 하 다.아래 의 예 를 통 해 알 수 있 듯 이 매우 간단 한 사전 기능 은 MVP 구 조 를 실현 하기 위해 Context 를 이리 저리 옮 겨 야 할 뿐만 아니 라 각종 리 셋 도 해 야 하기 때문에 논리 가 비교적 혼 란 스 러 워 보인다.

  • MVP 모드 사용
    MVP 모드 의 UML 그림 을 통 해 알 수 있 듯 이 MVP 를 사용 하려 면 적어도 다음 과 같은 절 차 를 거 쳐 야 합 니 다. 1. IPresenter 인 터 페 이 스 를 만 들 고 모든 업무 논리의 인 터 페 이 스 를 여기에 두 고 Presenter Compl 을 실현 합 니 다.
    인 터 페 이 스 는 여러 가지 실현 이 가능 하고 방식 이 다양 하 며 유연 하기 때문에 여기 서 해당 하 는 업무 기능 과 유닛 테스트 를 편리 하 게 찾 을 수 있 습 니 다. 2. IView 인 터 페 이 스 를 만 들 고 모든 보기 논리의 인 터 페 이 스 를 여기에 두 었 습 니 다. 사실은 현재 의 Activity / Fragment 는 UML 그림 에서 알 수 있 듯 이 Activity 에 IPresenter 가 포함 되 어 있 습 니 다.Presenter Compl 에는 IView 가 포함 되 어 있 고 Model 에 의존 하고 있다.Activity 에 서 는 IPresenter 에 대한 호출 만 보류 하고 다른 작업 은 모두 Presenter Compl 에 남 겨 두 어 3. Model 이 반드시 있어 야 하 는 것 은 아니 지만 반드시 View 와 Presenter 가 있 을 것 입 니 다.
    MVP 모드 의 예:
    저 는 제 가 이해 하 는 MVP 모델 로 간단 한 영어 사전 app 을 만 들 었 습 니 다. 이 를 통 해 MVP 모델 의 구체 적 인 실현 을 배 웠 습 니 다.
    먼저 View 층: View 층 에 View 인터페이스 와 UI 를 처리 하 는 MainActivity 가 있 습 니 다.
    package scut.cidian.View;
    
    /**
     * Created by yany on 2016/4/6.
     */
    public interface fanyiView {
        void init();//   
        void SetInfo(String str);//      
        void SetError();//      
    }

    MainActivity.java
    package scut.cidian.View;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import scut.cidian.Presenter.CidianPresenter;
    import scut.cidian.R;
    
    public class MainActivity extends AppCompatActivity implements fanyiView {
        private CidianPresenter cidianPresenter;
        private EditText et;
        private TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            init();
            findViewById(R.id.btnfanyi).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cidianPresenter.ModelGetData(et.getText().toString(), MainActivity.this);
                }
            });
        }
        public void init(){
            cidianPresenter = new CidianPresenter(this);
            et = (EditText) findViewById(R.id.editText);
            tv = (TextView) findViewById(R.id.tv);
        }//   
    
        @Override
        public void SetError() {
            tv.setText("     ,     ");
        }//      
    
        public void SetInfo(String str){
            tv.setText(str);
        }//      
    }
    

    그 다음 에 Model 층: 저 는 간단 하고 쉬 운 자바 빈 을 만 들 었 습 니 다. 공부 만 하기 때문에 저 는 안의 속성 을 private 로 설정 하지 않 습 니 다. set 와 get 방법 을 쓰 지 않도록 합 니 다.fanyi.java:
    package scut.cidian.Model;
    import java.util.List;
    
    public class fanyi {
        public String[] translation;
        public basic basic;
        public  static class basic{
            public String phonetic;
            public String[] explains;
        }
        public String query;
        public int errorCode;
        public List web;
        public static class wb{
                public String[] value;
                public String key;
            }
    }
    

    다음은 네트워크 데 이 터 를 읽 기 위 한 Model 계층 의 fanyimodel. java 와 그 인터페이스 Ifanymodel 입 니 다. Google 오픈 소스 의 Volley 프레임 워 크 를 사용 합 니 다. 사실 저 는 이 인 터 페 이 스 를 사용 하지 않 았 습 니 다. 나중에 확장 하기 편 하도록 추가 하 였 습 니 다.Ifanyimodel.java:
    package scut.cidian.Model;
    
    import android.content.Context;
    
    import scut.cidian.Presenter.onfanyiListener;
    
    /**
     * Created by yany on 2016/4/5.
     */
    public interface Ifanyimodel {
        void HandleData(String input,Context context,onfanyiListener listener);
        String fanyiToString(fanyi fy);
    }
    

    fanyimodel.java:
    package scut.cidian.Model;
    
    import android.content.Context;
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;
    import com.google.gson.Gson;
    import scut.cidian.Presenter.onfanyiListener;
    
    
    public class fanyimodel {
        private fanyi fy = new fanyi();
        public void HandleData(String input,Context context,final onfanyiListener listener){
            //  Volley             API      
            RequestQueue mQueue = Volley.newRequestQueue(context);
            StringRequest stringRequest = new StringRequest("http://fanyi.youdao.com/openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q="+input, new Response.Listener() {
                @Override
                public void onResponse(String s) {
                    // Gson       json   
                    Gson gson = new Gson();
                    fy = gson.fromJson(s.trim(),fy.getClass());
                    //        
                    listener.onSuccess(fanyiToString(fy));
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                    listener.onError();
                }
            });
            mQueue.add(stringRequest);
        }
        public String fanyiToString(fanyi fy){
            //      json  ,  UI      
            String strexplain = "  :";
            String strphonetic = "  :";
            String strweb = "    :";
            if (fy.basic == null){return "            ";}
            for (int i = 0; i
                strexplain +=fy.basic.explains[i]+"
    "
    ; if (i != fy.basic.explains.length-1 ) {strexplain +="\t\t\t\t";} } strphonetic += fy.basic.phonetic +"
    "
    ; for (int i = 0; i for(int j = 0; j { strweb += fy.web.get(i).value[j]+","; } strweb += fy.web.get(i).key+"
    "
    ; strweb += "\t\t\t\t\t\t\t"; } return strexplain+"
    "
    +strphonetic+"
    "
    +strweb; } }

    마지막 으로 Presenter 층: 이 안 에는 CidianPresenter 류 와 그 인터페이스 가 있 습 니 다. Model 층 에 비동기 스 레 드 가 네트워크 데 이 터 를 조작 하기 때문에 모니터 인터페이스 onfanyiListener 가 필요 합 니 다.onfanyiListener.java
    package scut.cidian.Presenter;
    
    import scut.cidian.Model.fanyi;
    
    /**
     * Created by yany on 2016/4/6.
     */
    public interface onfanyiListener {
        //      
        void onSuccess(String str);
        //       
        void onError();
    }
    

    ICidianPresenter.java
    package scut.cidian.Presenter;
    
    import android.content.Context;
    
    /**
     * Created by yany on 2016/4/5.
     */
    public interface ICidianPresenter {
        // View        Model 
        void InputToModel(String input,Context context);
    }
    

    CidianPresenter.java
    package scut.cidian.Presenter;
    
    import android.content.Context;
    
    import scut.cidian.Model.fanyi;
    import scut.cidian.Model.fanyimodel;
    import scut.cidian.View.fanyiView;
    
    /**
     * Created by yany on 2016/4/5.
     */
    public class CidianPresenter implements onfanyiListener {
        private fanyimodel fanyimodel;
        private fanyi fy;
        private fanyiView fyV;
    
        public  CidianPresenter(fanyiView fyV){
            this.fyV = fyV;
            fanyimodel = new fanyimodel();
        }//    ,   View     model  
    
        public void ModelGetData(String input, Context context){
            fanyimodel.HandleData(input, context, this);
        }// View        Model 
    
    
        public void onSuccess(String str) {
            fyV.SetInfo(str);
        }//    ,  UI  
    
        @Override
        public void onError() {
            fyV.SetError();
        }//    ,  UI      
    }
    

    CidianPresenter 는 View 인터페이스 인 스 턴 스 와 model 인 스 턴 스 를 통 해 두 모듈 을 연결 했다.
    결과:
    내 데모 다운로드 주소
    참고:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0313/2599.html http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0313/2599.html http://blog.csdn.net/feiduclear_up/article/details/46374653 http://www.cnblogs.com/liuling/archive/2015/12/23/mvp-pattern-android.html

    좋은 웹페이지 즐겨찾기