MVP architecture design patterns 1

In the actual development process, common to the design model has MVC, MVP, MVVM3 design patterns, the MVC design pattern, Activity in the C layer, but often both V and 2 part of the responsibility C is the C layer and V coupling layer is too high, resulting in the code or Fragment Activity bloated layer, does not have the scalability, so choosing MVP, MVVM design patterns become mainstream model.

From the beginning of this section, we will introduce the use of MVP design pattern. In the MVP mode is also divided into three characters:
M: the Model layer is responsible for data processing, including networking operation, database;
V: View layer, including the Activity, Fragment;
P: Presenter layer, and is responsible for M layer and a V layer interaction.

In fact, when using the MVP design, the main idea is to interface design, in MVC, C tend to complete the business logic functions View and C, in MVP, is often the View layer of abstraction for the interface, business logic is abstracted into Presenter layer, to achieve their duties.

Then on the first realization of a simple design pattern MVP
1.Model layer
mainly is to get in the Model layer data and then do the callback data

public interface IModel {
    /**
     * 网络请求加载数据,回调
     */
    void loadData(String appid,DataCallback callback);
    /**
     * 回调接口
     */
    interface DataCallback{
        void complete(String url);
    }
}

2.View layer

public interface IBaseView {
    /**
     * 数据显示
     */
    void showData(String url);
}

3.P layer
P layer is to achieve Model View layer and the binding layer, it is necessary to instantiate two Module.

public class IPresenter {
    private IBaseView mView;
    //在此实例化Model,不需要传入构造方法
    private IModel mModel = new ModelImpl();

    public IPresenter(IBaseView mView) {
        super();
        this.mView = mView;
    }

     /**
     * 实现View和Model的绑定
     * @param appid  View给P层的数据
     */
    public void fetch(String appid){
        if(mModel != null){
            mModel.loadData(appid,new IModel.DataCallback() {
                @Override
                public void complete(String url) {
                    //Model层的数据回调过来,在View层加载
                    mView.showData(url);
                }
            });
        }
    }

}

In the above code, there is no reason on the Model constructor is that, if passed in the constructor Model Presenter's, then you have to create an instance of the Model View layer, which would in turn establish contact and Model, so P layer made implementation class.

public class ModelImpl implements IModel {
    /**
     * 加载数据
     * @param appid
     * @param callback  回调
     */
    @Override
    public void loadData(String appid, DataCallback callback) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        IDataService dataService = retrofit.create(IDataService.class);
        Call<DataBean> call = dataService.data("getAppConfig.php", appid);
        call.enqueue(new Callback<DataBean>() {
            @Override
            public void onResponse(Call<DataBean> call, Response<DataBean> response) {
                String url = response.body().getUrl();
                //在此将数据回调,到P层
                callback.complete(url);
            }

            @Override
            public void onFailure(Call<DataBean> call, Throwable t) {

            }
        });

    }
}


ModelImp Model implementation class, the request for network operation, the callback data into the P layer.

In the View layer, you can click the button to get the data, get the callback data.

public class MainActivity extends AppCompatActivity implements IBaseView {
    private IPresenter presenter;
    private EditText et_appid;
    private Button btn_get;
    private TextView tv_data;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //initPresent
        initPresent();
        findView();
        initEvent();
    }

    private void initEvent() {
        btn_get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击按钮,就去向P层请求获取数据
                presenter.fetch(getEditText());
            }
        });
    }

    private void findView() {
        et_appid = findViewById(R.id.et_appid);
        btn_get = findViewById(R.id.btn_get);
        tv_data = findViewById(R.id.tv_data);
    }

    private void initPresent() {
        presenter = new IPresenter(this);
    }

    @Override
    public void showData(String url) {
        //url已经在P层获取了M层的回调,这边值需要显示
        tv_data.setText(url);
    }

    public String getEditText(){
        return et_appid.getText().toString();
    }
}

Thus obtaining a final response to the input data according to appid.
Here Insert Picture Description
At present, the above is achieved simply infrastructure MVP, then, we optimize the infrastructure.

Optimization 1: Memory Leak

private void initPresent() {
        presenter = new IPresenter(this);
    }

When we use the Presenter View layer, and have to go to create a Presenter instance, because the P and V is a one to one relationship, so each time you create a new View, need to create an instance of P, P and this holds View references, will be a memory leak.

Memory leak problem: because the View layer and the P layer is associated, when the View layer need to get the data, the data will get the whereabouts of the Model layer by layer P; quit if the current View, the corresponding P layer may still be time-consuming operation, resulting in View can not quit, cause a memory leak.

So you can create a Presenter base class, and implement them binding and removal of the View, that is, in onCreate time, it bound, it is removed onDestory time.

So to do something for P and V operations.

public class BasePresenter<V> {
    /**
     * 使用弱引用创建View
     */
    protected WeakReference<V> mView;
    /**
     * 关联View
     */
    public void attachView(V view){
        mView = new WeakReference<>(view);
    }
    /**
     * 解除关联
     */
    public void detachView(V view){
        if(mView != null){
            mView.clear();
        }
    }

    protected V getView(){
        return mView.get();
    }
}


Creating an Activity base class BaseActivity

public abstract class BaseActivity<V,P extends BasePresenter<V>> extends AppCompatActivity {
    protected P mPresenter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建Presenter,并关联View
        mPresenter = createPresenter();
        mPresenter.attachView((V) this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mPresenter != null){
            mPresenter.detachView((V) this);
            mPresenter = null;
        }
    }

    protected abstract P createPresenter();
}

Before, when we use the Presenter View layer, and create a Presenter is instantiated using the new keyword, and then call methods to fetch the View and the Model binding. In this BaseActivity created, the onCreate method is an example of this Presenter, and then bind the current View.

So in real Activity in to inherit this BaseActivity when you do not need to create, for each of an Activity we are like this.

public class MainActivity extends BaseActivity<IMainView, MainPresenter> implements IMainView {
    private EditText et_appid;
    private Button btn_get;
    private TextView tv_data;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findView();
        initEvent();
    }

    @Override
    protected MainPresenter createPresenter() {
        //在这里已经将Presenter初始化
        return new MainPresenter();
    }

    private void initEvent() {
        btn_get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击按钮,就去向P层请求获取数据
                mPresenter.fetch(getEditText());
            }
        });
    }

    private void findView() {
        et_appid = findViewById(R.id.et_appid);
        btn_get = findViewById(R.id.btn_get);
        tv_data = findViewById(R.id.tv_data);
    }


    @Override
    public void showData(String url) {
        //url已经在P层获取了M层的回调,这边值需要显示
        tv_data.setText(url);
    }

    public String getEditText(){
        return et_appid.getText().toString();
    }
}

For each Presenter, you do not need to go to create a constructor method, the direct successor to BasePresenter.

public class MainPresenter extends BasePresenter<IMainView> {
    //在此实例化Model,不需要传入构造方法
    private IModel mModel = new ModelImpl();
    /**
     * 实现View和Model的绑定
     * @param appid  View给P层的数据
     */
    public void fetch(String appid){
        if(mModel != null){
            mModel.loadData(appid,new IModel.DataCallback() {
                @Override
                public void complete(String url) {
                    //Model层的数据回调过来,在View层加载
                   getView().showData(url);
                }
            });
        }
    }

}

By this method, to achieve a binding V and P, and do not need to hand out a new instance, it is more important is to solve the problem of memory leaks.
In development projects after, you can use this framework to develop MVP design pattern, of course, not have to use MVP, to choose the right design pattern based on the actual situation, well, MVP will briefly introduced here, will be back continue to update.

Published 15 original articles · won praise 5 · Views 612

Guess you like

Origin blog.csdn.net/qq_33235287/article/details/104210276