美文网首页
Android MVC架构和MVP架构以及区别

Android MVC架构和MVP架构以及区别

作者: SimpleLife_9f4a | 来源:发表于2017-09-02 00:59 被阅读0次

一、MVC架构:
MVC就是Model-View-Controller:

        (数据模型)Model:数据的封装和保存,业务逻辑和实体模型
        (视图)View:视图界面,对应于布局文件
        (控制器)Controller:业务逻辑,对应于Activity、Fragment等

它们之间的关系如下图所示:
View传送指令到Controller,Controller完成业务逻辑后,改变Model的状态,Model将新的数据发送到View,这就是MVC模式的处理逻辑。



实例【以Retrofit联网为例】


先看主页布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btnMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="click here to connect by retrofit"
        android:textAllCaps="false" />

    <TextView
        android:id="@+id/tvMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp" />

</LinearLayout>

作者:HELLO丶GUY
链接:http://www.jianshu.com/p/894420ac8fdc
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

点击按钮进行联网并且把联网获取到的数据显示在textview中,如果失败则显示联网数据获取失败。
这里主要贴出model与controller包下的代码。

model-KpiInfoModel.java

public interface KpiInfoModel {
    void getKpiInfo(Map<String, String> params, OnKpiInfoListener listener);
}

model-OnKpiInfoListener.java

public interface OnKpiInfoListener {
    void onSuccess(ResultBean<KpiInfoPo> resultBean);

    void onFailed();
}

以上KpiInfoModel 主要是用于提供进行联网动作的入口方法,这里看起来会有一点吃力。同样的,OnKpiInfoListener 提供了联网以后的操作方法。然后我们需要去实现这两个接口,并且重写里面的方法。

model-KpiInfoModelImp.java

public class KpiInfoModelImp implements KpiInfoModel {

    @Override
    public void getKpiInfo(Map<String, String> params, final OnKpiInfoListener listener) {
        Call<ResultBean<KpiInfoPo>> call = MainApplication.factory.getKpiInfo(params);
        call.enqueue(new Callback<ResultBean<KpiInfoPo>>() {
            @Override
            public void onResponse(Call<ResultBean<KpiInfoPo>> call, Response<ResultBean<KpiInfoPo>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    listener.onSuccess(response.body());
                } else {
                    onFailure(call, null);
                }
            }

            @Override
            public void onFailure(Call<ResultBean<KpiInfoPo>> call, Throwable t) {
                listener.onFailed();
            }
        });
    }
}

作者:HELLO丶GUY
链接:http://www.jianshu.com/p/894420ac8fdc
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以上就是联网的model,并且以及写好了实现类,用于在controller中使用。

controller-MainActivity.java

public class MainActivity extends AppCompatActivity implements OnKpiInfoListener {

    private Button btnMain;
    private TextView tvMain;
    private KpiInfoModelImp kpiInfoModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.acticity_home);
        initView();
        kpiInfoModel = new KpiInfoModelImp();
        btnMain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Map<String, String> params = new HashMap<>();
                params.put("user_id", "198");
                kpiInfoModel.getKpiInfo(params, MainActivity.this);
            }
        });
    }

    private void initView() {
        btnMain = (Button) findViewById(R.id.btnMain);
        tvMain = (TextView) findViewById(R.id.tvMain);
    }

    @Override
    public void onSuccess(ResultBean<KpiInfoPo> resultBean) {
        tvMain.setText(resultBean.getResult_data().toString());
    }

    @Override
    public void onFailed() {
        tvMain.setText("数据获取失败");
    }
}

作者:HELLO丶GUY
链接:http://www.jianshu.com/p/894420ac8fdc
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

通过以上实例代码可以看出,activity只起到了和view互动的作用,只针对view进行操作,而联网部分则全部是在model里,这样对与业务的分离具有好处。但也具有一定的劣势,可以看出model的这块代码较为琐碎。

二、MVP架构:
MVP是Model-View-Presenter,它们的作用如下:


Model:业务逻辑和实体模型,用来操作实际的数据,包含Bean和Model的抽象接口来降低耦合。
      View:就是Android中的视图,需要建立一个View的抽象接口View Interface。通过实现View的接口来实现View与Presenter的交互,从而降低耦合。对应于Activity,负责View的绘制与用户交互;
      Presenter:View和Model的中间枢纽,处理和用户交互的逻辑。

作者:ibinbin
链接:http://www.jianshu.com/p/bd99bda72912
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

通过一个物联网的例子来理解MVP模式:

View层:

/**
  * ViewInterface
  * 定义一些通用的view接口
 */
public interface LoadDataView {
    /***
     * 耗时操作,加载数据,显示Progress
     */
    void showLoading();
    /***
     * 隐藏Progress
     */
    void hideLoading();
}

/**
 * 更细小的,用来显示图书细节的View接口
  */
public interface LoadBookView extends LoadDataView {
        void showDetailsView(BookEntity entity);
}

/***
 * Fragment,属于View层,实现了ViewInterface(LoadBookView)
 */
public class BookDetailFragment extends Fragment implements LoadBookView{
    /**图书条形码ISBN号*/
    public static final String ISBN = "9787121060748";
    /**持Presenter对象*/
    private BookDetailsPresenter presenter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initWidget();
        presenter = new BookDetailsPresenter(getActivity(), ISBN); // 实例化一个presenter对象
        presenter.setView(this); //让Presenter持一个ViewInterface实例(LoadBookView)
        presenter.loadData(); //告诉Presenter快给我加载Data
    }    

     @Override
    public void showDetailsView(BookEntity entity) {
        //更新UI等操作
    }

    @Override
    public void showLoading() {
        rlProgress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        rlProgress.setVisibility(View.GONE);
    }
}

作者:ibinbin
链接:http://www.jianshu.com/p/bd99bda72912
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2、Presenter层:

public class BookDetailsPresenter {
    /**持一个Model层的对象,用来从网页接口Rest Api中提取数据*/
    private RestApi restApi = null;
    /**一个ViewInterface对象,用来回调Data给View*/
    private LoadBookView loadBookView;
    private String isbn;

    public BookDetailsPresenter(Context context, String isbn) {
        restApi = new RestApiImpl(context);
        this.isbn =isbn;
    }
    public void setView(LoadBookView loadBookView) {
        this.loadBookView = loadBookView;
    }
    public void loadData() {
        loadBookView.showLoading();
        //耗时操作,开个线程异步的加载数据
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                restApi.getBookDetailByIsbn(isbn, bookDetailsCallback);
            }
        });
        thread.start();
    }
    //匿名内部类,接收bookDetailCallback的回调数据
    private RestApi.BookDetailsCallback bookDetailsCallback = new RestApi.BookDetailsCallback() {
        @Override
        public void onBookEntityLoaded(BookEntity bookEntity) {
            notifyDataLoadedSuccessful(bookEntity);
            BookDetailsPresenter.this.loadBookView.hideLoading();
        }

        @Override
        public void onError(Exception e) {
            //异常后的相关处理
        }
    };

    /***
    * 通知获取数据成功了,赶快通知UI更新吧
    */
    private void notifyDataLoadedSuccessful(final BookEntity bookEntity) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                BookDetailsPresenter.this.loadBookView.showDetailsView(bookEntity);
            }
        });
    }  
}

作者:ibinbin
链接:http://www.jianshu.com/p/bd99bda72912
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3、Model层:

/***
* 整个应用程序需要的数据实体类
*/
public class BookEntity {
    //一些set,get方法
}

/**
 * 一个接口,用来从rest api api获得数据,它的实现在RestApiImpl中
 */
public interface RestApi {
    String API_ISBN_BASE_URL = "https://api.douban.com/v2/book/isbn/";
    /***
    * 更细小的接口,用来将获取到的数据,回调给它的调用者
    */
    interface BookDetailsCallback {
        void onBookEntityLoaded(BookEntity bookEntity);
        void onError(Exception e);
    }
    /**
     * 从网络获取数据,然后通过bookDetailCallback回调给Presenter
     * @param isbn
     * @param bookDetailsCallback
     */
    void getBookDetailByIsbn(final String isbn, final BookDetailsCallback bookDetailsCallback);

}

作者:ibinbin
链接:http://www.jianshu.com/p/bd99bda72912
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三、MVP和MVC的区别
MVP架构:

      View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。
      Presenter与View的交互是通过接口来进行的。
      通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。

MVC架构:

      View可以与Model直接交互。
      Controller是基于行为的,并且可以被多个View共享。
      可以负责决定显示哪个View。

MVC跟的MVP进行对比,就是省去mvp中的presenter,mvp中把mainactivity的接口实现类传入到presenter中,来拿到数据去进行model中的业务逻辑,model中再回调mainactivity的那个接口实现来进行视图更新,而mvc则是直接用mainactivity来与model打交道。

相关文章

网友评论

      本文标题:Android MVC架构和MVP架构以及区别

      本文链接:https://www.haomeiwen.com/subject/nodljxtx.html