企业级MVP架构设计

《MVP架构设计模式1》中,着重介绍过MVP架构设计,以及可能会出现内存泄漏的优化,那么在本节中,将会深入企业,看企业级的MVP架构是如何完成 的。

1、BaseActivity

在MVP架构中,Activity已经属于View层,不再是MVC中的C层,因此Activity主要就是负责加载View,或者向P层请求获取数据。

public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(getLayout());
        initView();
        initData();
        initListener();
    }
    //初始化监听
    protected abstract void initListener();

    //初始化数据
    protected abstract void initData();

    //初始化View,findViewById...
    protected abstract void initView();

    protected abstract int getLayout();
}

2、BaseModel

在MVP架构中,Model层主要负责网络请求或者数据库等操作,而且之和P层有直接的关系,因此在使用Model时只能是BasePresenter的实现类使用。

public abstract class BaseModel<P extends BasePresenter> {
    
    public P mPresenter;
    
    public BaseModel(P mPresenter){
        this.mPresenter = mPresenter;
    }
}

3、BasePresenter

在MVP架构中,P层属于建立Model层和View层的桥梁,既要获取View层的引用,又要与Model层建立连接回调数据,还要防止内存泄漏的情况发生。

public abstract class BasePresenter<V extends BaseActivity,M extends BaseModel> {

    //获取View的引用
    private V mView;
    //获取Model层的引用
    private M mModel;
    
    public BasePresenter(){
        this.mModel = getModelInstance();
    }
    //子类实例化,获取特定的Model
    protected abstract M getModelInstance();

    //绑定View
    public void attachView(V mView){
        this.mView = mView;
    }

    //解绑View
    public void detachView(V mView){
        if(this.mView != null){
            this.mView = null;
        }
    }
}

3部分完成之后,需要完善BaseActivity。

public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements View.OnClickListener {

    protected P mPresenter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(getLayout());
        initView();
        initData();
        initListener();
        //初始化P层
        mPresenter = createPresenter();
        //绑定当前View
        mPresenter.attachView(this);
    }

    protected abstract P createPresenter();

    //初始化监听
    protected abstract void initListener();

    //初始化数据
    protected abstract void initData();

    //初始化View,findViewById...
    protected abstract void initView();

    protected abstract int getLayout();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPresenter.detachView(this);
    }
}

4、MVP架构的使用

设计一个登陆功能,需要输入用户名和密码,点击按钮登录,做回调。

在做回调的时候,使用契约合同,面向接口编程。

public interface ILoginContract {
    
    public interface M{
        void requestLogin(String username,String password) throws Exception;
    }
    
    interface VP{
        void requestLogin(String username,String password);
        void responseLoginResult(boolean status);
    }
}

(1)LoginActivity

登录界面需要持有LoginPresenter的引用,并且实现契约合同中的VP接口发起请求和回调;在点击登录按钮的时候,调用requestLogin方法,此时就是去向P层请求获取数据。

public class LoginActivity extends BaseActivity<LoginPresenter> implements ILoginContract.VP {

    private EditText et_username,et_password;
    private Button btn_login;
    private TextView tv_login;

    @Override
    protected LoginPresenter createPresenter() {
        return new LoginPresenter();
    }

    @Override
    protected void initListener() {
        btn_login.setOnClickListener(this);
    }

    @Override
    protected void initData() {

    }

    @Override
    protected void initView() {
        et_username = findViewById(R.id.et_username);
        et_password = findViewById(R.id.et_password);
        btn_login = findViewById(R.id.btn_login);
        tv_login = findViewById(R.id.tv_login);
    }

    @Override
    protected int getLayout() {
        return R.layout.activity_login;
    }

    @Override
    public void onClick(View v) {
        String username = et_username.getText().toString();
        String password = et_password.getText().toString();
        //请求登录
        requestLogin(username,password);
    }

    @Override
    public void requestLogin(String username, String password) {
        //向P层请求数据
        mPresenter.requestLogin(username,password);
    }

    @Override
    public void responseLoginResult(boolean status) {
        //接受回调
        if(status){
            tv_login.setText("已登录成功");
        }
    }
}

(2)LoginPresenter

当View层发起请求的时候,P层需要向Model层请求获取数据,在这里就需要做部分业务逻辑,判断输入的信息的合法性。

public class LoginPresenter extends BasePresenter<LoginActivity,LoginModel> implements ILoginContract.VP{

    @Override
    protected LoginModel getModelInstance() {
        return new LoginModel(this);
    }

    @Override
    public void requestLogin(String username, String password)  {
        //向Model层请求获取数据

        //.....校验信息完整性
        try {
            mModel.requestLogin(username,password);

        } catch (Exception e) {
            e.printStackTrace();
            //异常处理,保存到日志
        }
    }

    @Override
    public void responseLoginResult(boolean status) {
        //向View层回调
        mView.responseLoginResult(status);
    }
}

(3)LoginModel

在Model层中,真正执行requestLogin发起网络请求,将请求得到的数据,通过responseLoginResult回调接口返回P层。

public class LoginModel extends BaseModel<LoginPresenter> implements ILoginContract.M{

    public LoginModel(LoginPresenter mPresenter) {
        super(mPresenter);
    }

    @Override
    public void requestLogin(String username, String password) throws Exception {
        //网络请求返回数据
        mPresenter.responseLoginResult(true);
    }
}

在P层中,持有了View层的引用,因此将数据返回View层,View层接收到数据后,更新UI界面。

5、MVP架构的升级

(1)在之前使用契约合同的时候,需要自己手写并主动实现,那么在这里就可以做一个升级,开发者不需要主动去实现接口。

面向接口编程,就是父类告诉子类,让子类干什么,也就是说,在父类中传入一个接口,让子类去实现实例化接口,实现其中的方法。

public abstract class SuperBase<CONTRACT> {
    //获取特定的契约合同
    public abstract CONTRACT getContract();
}

在Base层,需要传入这个接口,这是强制的,而不需要开发者主动去implements接口。

Model层:

public abstract class BaseModel<P extends BasePresenter,CONTRACT> extends SuperBase<CONTRACT> {

    public P mPresenter;

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

Presenter层:

public abstract class BasePresenter<V extends BaseActivity,M extends BaseModel,CONTRACT> extends SuperBase<CONTRACT> {

    //获取View的引用
    protected V mView;
    //获取Model层的引用
    protected M mModel;

    public BasePresenter(){
        this.mModel = getModelInstance();
    }
    //获取特定的Model
    protected abstract M getModelInstance();

    //绑定View
    public void attachView(V mView){
        this.mView = mView;
    }

    //解绑View
    public void detachView(V mView){
        if(this.mView != null){
            this.mView = null;
        }
    }
}

View层:

public abstract class BaseActivity<P extends BasePresenter,CONTRACT> extends AppCompatActivity implements View.OnClickListener {

    protected P mPresenter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(getLayout());
        initView();
        initData();
        initListener();
        //初始化P层
        mPresenter = createPresenter();
        //绑定当前View
        mPresenter.attachView(this);
    }

    //契约接口
    protected abstract CONTRACT getContract();
    
    protected abstract P createPresenter();

    //初始化监听
    protected abstract void initListener();

    //初始化数据
    protected abstract void initData();

    //初始化View,findViewById...
    protected abstract void initView();

    protected abstract int getLayout();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPresenter.detachView(this);
    }
}

在使用的时候,就可以面向接口编程。

在View层可以通过Presenter层的getContract获取接口,进行方法调用和回调

	@Override
    protected ILoginContract.VP getContract() {
        return new ILoginContract.VP() {
            @Override
            public void requestLogin(String username, String password) {
                //P层同样需要面向接口
                mPresenter.getContract().requestLogin(username,password);
            }

            @Override
            public void responseLoginResult(boolean status) {
                if(status) {
                    tv_login.setText("登录成功");
                }
            }
        };
    }

相较于之前的MVP架构设计,这是一种全新的架构设计思路,采用了面向接口编程,扩展性更高,耦合度降低。

6、Fragment的MVP架构设计

其实Fragment和Activity在MVP中,都属于View层,形式差不多,只是加载View的时候些许不同,Fragment的主要职责就是显示View。

View层:

public abstract class BaseFragment<P extends BaseFragmentPresenter,CONTRACT> extends Fragment implements View.OnClickListener {

    //p层
    protected P mPresenter;
    View rootView;
    
    //创建接口
    protected abstract CONTRACT getContract();
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mPresenter = createPresenter();
        mPresenter.attachView(this);
    }

    protected abstract P createPresenter();

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(rootView == null) {
            rootView = LayoutInflater.from(getContext())
                    .inflate(getLayout(), container, false);
        }
        initView(rootView);
        initListener();
        return rootView;
    }

    protected abstract void initListener();

    protected abstract void initView(View rootView);

    protected abstract int getLayout();

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
    }

    protected void initData() {

    }

    @Override
    public void onDetach() {
        super.onDetach();
        if(mPresenter != null){
            mPresenter.detachView(this);
        }
    }
}

Presenter层:

public abstract class BaseFragmentPresenter<V extends BaseFragment,M extends BaseFragmentModel,CONTRACT> extends SuperBase<CONTRACT> {

    protected V mFragment;
    protected M mModel;

    public BaseFragmentPresenter(){
        this.mModel = getModelInstance();
    }

    protected abstract M getModelInstance();

    //绑定View
    public void attachView(V mFragment){
        this.mFragment = mFragment;
    }

    //解绑View
    public void detachView(V mFragment){
        if(mFragment != null){
            this.mFragment = null;
        }
    }
}

Model层:

public abstract class BaseFragmentModel<P extends BaseFragmentPresenter,CONTRACT> extends SuperBase<CONTRACT> {

    protected P mPresenter;
    public BaseFragmentModel(P mPresenter){
        this.mPresenter =  mPresenter;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值