MVC到MVP(mvp实例-内存泄漏优化)演变

MVC架构与三级模型

1.View接受到用户操作
2.View将用户的操作,交给Controller.
3.Controller完成具体的业务逻辑。
4.得到结果封装Model,在进行View更新。
MVC流程图
从图中可以看出:
Controller(Activity,控制层 - 面向业务逻辑的具体操作 ) 是作为一个媒介,处于Model(模型层 - 面向需求模型,数据模型)和View(视图层 - 面向用户渲染画面UI)之间.Model和View之间有紧密的联系,耦合性偏强。可以看出这样会导致Activity要做的事情非常之多,既要做View层的职责,也有做Model层的职责。这明显违反的面向对象的单一原则。这就衍生出MVP和MVVM架构思想。
在这里插入图片描述
在这里插入图片描述

MVP模型

在这里插入图片描述
首先要注意的一点是Activity在MVC中是属于Controller层,但是在MVP中它是属于View层。

关系:

  1. View接受到用户的操作
  2. View把用户的操作,交给Presenter
  3. Persenter 控制Model进行业务逻辑处理
  4. Persenter 处理完后,数据封装到Model
  5. Persenter 收到通知后,更新View

方式: 是双向的通信

优点 :1

  1. View层和Model层完全分离
  2. 所有的逻辑交互都是在Persenter
  3. MVP分层较为严谨

MVP思想精髓:
1.View层之需要面向Presenter层,不需要知道Model;
2.Model层只需要面向Presenter层,不需要知道View层;
3.View层和Model层逻辑交互在Presenter.
4.巧妙的解耦view与model

在这里插入图片描述
直接上代码
代码的层级
在这里插入图片描述
LoginActivity

public class LoginActivity extends BaseView<LoginPresenter, LoginContract.View> {

    private EditText nameEt;
    private EditText pwdEt;
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        initView();
    }

    // 初始化控件
    private void initView() {
        nameEt = findViewById(R.id.et_name);
        pwdEt = findViewById(R.id.et_pwd);
        btn = findViewById(R.id.bt_login);
    }

    // 点击事件
    public void doLoginAction(View view) {
        String name = nameEt.getText().toString();
        String pwd = pwdEt.getText().toString();
        // 发起需求,让Presenter处理
        p.getContract().requestLogin(name, pwd);
    }

    @Override
    public LoginContract.View getContract() {
        return new LoginContract.View<UserInfo>() {
            @Override
            public void handlerResult(UserInfo userInfo) {
                if (userInfo != null) {
                    Toast.makeText(LoginActivity.this, userInfo.toString(), Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(LoginActivity.this, "登录失败!", Toast.LENGTH_SHORT).show();
                }
            }
        };
    }

    @Override
    public LoginPresenter getPresenter() {
        return new LoginPresenter();
    }
}

BaseModel

// 接收到P层交给它的需求(基类)
public abstract class BaseModel<P extends BasePresenter, CONTRACT> {

    protected P p;

    // 业务结束,通过Presenter调用契约、合同(接口中的方法)void responseResult(T t)

    public BaseModel(P p) {
        this.p = p;
    }

    public abstract CONTRACT getContract();
}

BasePresenter

// Presenter基类
public abstract class BasePresenter<V extends BaseView, M extends BaseModel, CONTRACT> {

    protected M m;
    // 绑定View层弱引用
    private WeakReference<V> vWeakReference;

    public BasePresenter() {
        m = getModel();
    }

    public void bindView(V v) {
        vWeakReference = new WeakReference<>(v);
    }

    public void unBindView() {
        if (vWeakReference != null) {
            vWeakReference.clear();
            vWeakReference = null;
            System.gc();
        }
    }

    // 获取View,P -- V
    public V getView() {
        if (vWeakReference != null) {
            return vWeakReference.get();
        }
        return null;
    }

    // 获取子类具体契约(Model层和View层协商的共同业务)
    public abstract CONTRACT getContract();

    public abstract M getModel();
}

BaseView

// View层基类
public abstract class BaseView<P extends BasePresenter, CONTRACT> extends Activity {

    protected P p;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 弱引用
        p = getPresenter();
        // 绑定
        p.bindView(this);
    }

    // 让P层做什么需求
    public abstract CONTRACT getContract();

    // 从子类中获取具体的契约
    public abstract P getPresenter();

    // 如果Presenter层出现了异常,需要告知View层
    public void error(Exception e) {}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 解除绑定
        p.unBindView();
    }
}

BaseEntity

public class BaseEntity {

    private int code;
    private boolean success;
    private String error;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
}

UserInfo

public class UserInfo extends BaseEntity {

    private String company;
    private String name;

    public UserInfo() {
    }

    public UserInfo(String company, String name) {
        this.company = company;
        this.name = name;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "company='" + company + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

HttpEngine

// 有可能是共有的Model
public class HttpEngine<P extends LoginPresenter> {

    private P p;

    public HttpEngine(P p) {
        this.p = p;
    }

    public void post(String name, String pwd) {
       if ("mvp".equalsIgnoreCase(name) && "123".equals(pwd)) {
            p.getContract().responseResult(new UserInfo("测试", "小刘"));
        } else {
            p.getContract().responseResult(null);
        }
    }
}

LoginContract

// 将Model层、View层、Presenter层协商的共同业务,封装成接口
// 契约、合同
public interface LoginContract {

    interface Model {
        // Model层子类完成方法的具体实现----------------2
        void executeLogin(String name, String pwd) throws Exception;
    }

    interface View<T extends BaseEntity> {
        // 真实的项目中,请求结果往往是以javabean--------------4
        void handlerResult(T t);
    }

    interface Presenter<T extends BaseEntity> {
        // 登录请求(接收到View层指令,可以自己做,也可以让Model层去执行)-----------1
        void requestLogin(String name, String pwd);

        // 结果响应(接收到Model层处理的结果,通知View层刷新)---------------3
        void responseResult(T t);
    }
}

LoginMode

// 接收到P层交给它的需求
public class LoginMode extends BaseModel<LoginPresenter, LoginContract.Model> {

    public LoginMode(LoginPresenter loginPresenter) {
        super(loginPresenter);
    }

    @Override
    public LoginContract.Model getContract() {
        return new LoginContract.Model() {
            @Override
            public void executeLogin(String name, String pwd) throws Exception {
                if ("mvp".equalsIgnoreCase(name) && "123".equals(pwd)) {
                    p.getContract().responseResult(new UserInfo("测试", "小刘"));
                } else {
                    p.getContract().responseResult(null);
                }
            }
        };
    }
}

LoginPresenter

public class LoginPresenter extends BasePresenter<LoginActivity, LoginMode, LoginContract.Presenter> {

    @Override
    public LoginContract.Presenter getContract() {
        // 既要履行View给它的需求,又要分配工作给Model去完成这个需求
        return new LoginContract.Presenter<UserInfo>() {
            @Override
            public void requestLogin(String name, String pwd) {
                try {
                    // 三种风格(P层很极端,要么不做事只做转发,要么就是拼命一个人干活)
                    m.getContract().executeLogin(name, pwd);

                    // 第二种,让功能模块去工作(Library:下载、请求、图片加载)
//                    HttpEngine engine = new HttpEngine<>(LoginPresenter.this);
//                    engine.post(name, pwd);

                    // P层自己处理(谷歌例子)
//                    if ("mvp".equalsIgnoreCase(name) && "123".equals(pwd)) {
//                        responseResult(new UserInfo("测试", "小刘"));
//                    } else {
//                        responseResult(null);
//                    }

                    // 内存泄露测试
//                    new Thread(new Runnable() {
//                        @Override
//                        public void run() {
//                            SystemClock.sleep(50000);
//                        }
//                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void responseResult(UserInfo userInfo) {
                // 不管谁完成需求,有结果就告知View层
                getView().getContract().handlerResult(userInfo);
            }
        };
    }

    @Override
    public LoginMode getModel() {
        return new LoginMode(this);
    }
}


以上就是所有代码的类,可以直接参考去理解MVP.看太多理论不如实际的敲个3遍,希望对大家的学习有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值