mvp optimize your code

What is an MVP?

Most Valuable Player? No, no, although I like watching NBA, this MVP is not another MVP.
MVP here refers to a development mode in Android.
It divides the code into three layers: M (Model), V (View), and P (Presenter).

Serious version:
M layer (model): data model / processing layer. Responsible for data processing and data provision, such as network requests, database operations
V layer (view): view display layer. Responsible for interface display, such as Activity, Fragment
P layer (presenter): business logic layer. Responsible for business logic services, it is the bridge between the V layer and the M layer

640?wxfrom=5&wx_lazy=1MVP diagram 1

You can also help to understand (restaurant version):
M layer (model): chef. Responsible for cooking
V layer (view): customers. Order to eat
P floor (presenter): waiter. Provide various services such as ordering and serving

640MVP diagram 2

The difference from the MVC mode:
In MVC, the V layer and the M layer can communicate with each other, but in the MVP, the V layer and the M layer are not communicated.
According to the restaurant version, in MVC, the customer can directly tell the chef what dish to eat, and the chef will bring the dish to you directly after it is done, while in MVP, the process from ordering to dining can only be completed through the waiter.

What are the benefits of using MVP?

In abstract terms:
MVP can reduce the degree of code coupling and improve the structural clarity, readability, maintainability and reusability of the code.

Specifically (refer to JessYan's example):
Now there is such a requirement: Activity obtains data from the network and displays it on the A control.
If you don't need MVP, you can directly write the code for obtaining and displaying in the Activity, and you can write it soon.

But now the requirements have changed:
1. It is required to add the cache function. If there is data locally, the data is obtained from the local, and then the latest data is obtained from the network for replacement
. 2. The data is required to be displayed on the B control instead of the A control.

If the code is written by you, it is easier to change it, but if it is developed by a team and the code is not written by you, you need to spend time re-reading the logic before starting to change, and if you make a mistake, it will affect the previous function already written.

But developing with the MVP pattern is different. Due to its clear division of labor structure, the V layer is only responsible for data display, the P layer is only responsible for business logic, and the M layer is only responsible for data acquisition/processing. So it's a lot easier to change.
For the changing requirement 1: we only need to add logical judgment to the P layer (first obtain from the local, and then obtain it from the network), and then add a method to obtain data from the local at the M layer.
For the changing requirement 2: We only need to modify the display method of the acquired data in the V layer, from control A to control B.

Of course, there are other advantages such as reusability, which will not be discussed in detail here.
As for the "disadvantage", it will increase the amount of code accordingly. There are gains and losses, but the gains outweigh the losses.

specific use

Take such a scenario as an example:
Get the movie data "on display" from the network, display the data on the page if the acquisition is successful, and give a corresponding prompt if the acquisition fails.

Four parts need to be written: Model layer, View layer, Presenter layer, interface

The interface
is responsible for "connecting" the three layers of MVP for method invocation and data flow. It also facilitates unit testing.

The IView
View layer interface defines the methods that the View layer needs to implement, and the P layer calls back to notify the View layer through this interface.

public interface IMovieView {
    //成功获取到电影数据
    void getMovieSuccess(List<MovieRes> list, int type);
    //获取电影数据失败
    void getMovieFail(int status, String desc, int type);
}

The IModel
Model layer interface defines the methods that the Model layer needs to implement. The P layer calls the M layer's data acquisition/processing methods through this interface.

public interface IMovieMoel{
    //请求正在上映的电影数据
    Observable getPlayingMovie(int start, int count);
    ...
}

The Model layer
implements the methods in the IModel interface and is responsible for data acquisition/processing.

public class MovieModel implements IMovieMoel{

    @Override
    public Observable getPlayingMovie(int start,int count) {
        //提供数据源
        return DevRing.httpManager().getService(MovieApiService.class).getPlayingMovie(start, count);
    }
    ...
}

The Presenter layer
handles business logic, calls the M layer to obtain data, and calls the V layer to transmit the display data.

public class MoviePresenter {
    private IMovieView mIView;
    private IMovieModel mIModel;

    public MoviePresenter(IMovieView iMovieView, IMovieMoel iMovieMoel) {
        mIView = iMovieView;
        mIModel = iMovieModel;
    }

    /**
     * 获取正在上映的电影
     *
     * @param start 请求电影的起始位置
     * @param count 获取的电影数量
     * @param type  类型:初始化数据INIT、刷新数据REFRESH、加载更多数据LOADMORE
     */
    public void getPlayingMovie(int start, int count, final int type) {

        DevRing.httpManager().commonRequest( mIModel.getPlayingMovie(start, count),
         new CommonObserver<HttpResult<List<MovieRes>>>() {
            @Override
            public void onResult(HttpResult<List<MovieRes>> result) {
                if (mIView != null) {
                    mIView.getMovieSuccess(result.getSubjects(), type);
                }
            }

            @Override
            public void onError(int errType, String errMessage) {
                if (mIView != null) {
                    mIView.getMovieFail(errType, errMessage, type);
                }
            }
        }, RxLifecycleUtil.bindUntilDestroy(mIView));
    }

    ...

     /**
     * 释放引用,防止内存泄露
     */
    public void destroy() {
        mIView = null;
    }
}

The View layer
implements the methods in the IView interface to display the acquired data

public class MovieFragment implements IMovieView {
    //获取电影数据成功的网络请求回调
    @Override
    public void getMovieSuccess(List<MovieRes> list, int type) {
        //成功,对数据进行展示
        ....
    }

    //获取电影数据失败的网络请求回调
    @Override
    public void getMovieFail(int status, String desc, int type) {
        //失败,界面上做出相应提示
        ...
    }
}

After completing the above steps, when the View layer is initialized, call the Presenter layer method.

@Override
protected void initData() {
      mPresenter = new MoviePresenter(this, new MovieModel());
      mPresenter.getPlayingMovie(start, mCount, type);
}

Another point to note:
if the Presenter layer holds a reference to the View layer, remember to set the reference to the View layer in the Presenter layer to null when the V layer is destroyed to avoid memory leaks caused by the failure of the View layer to recycle.

@Override
public void onDestroy() {
     super.onDestroy();
     if (mPresenter != null) {
          mPresenter.destroy();
          mPresenter = null;
     }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324772296&siteId=291194637
MVP