MVP基础篇

2021-01-29  本文已影响0人  Method
js.jpg

MVC

简介

将应用组件分为三部分:模型-视图-控制器

mvc.png

那在Android里是什么充当View,什么充当Model,什么充当Controller呢?

View:Acitivity(View)、Fragment(View)视图,在android里xml布局转成View后,加载到了Activity/Fragment里了。

Controller:Controller对应着Activity/Fragment,绑定UI,处理各种业务。

Model:数据的获取,存储,更新

优点

view与model隔离,view换了,model不影响。model换其他的数据源,view层也不受影响。一个view可以连接多个model,有些model可以复用。比如说你这个页面需要用户信息,另外一个界面也需要用户信息。

缺点

这里我们主要指Android上的缺点,不适合在Android开发上使用。在Android开发中,View的相关内容和Controller都写到一起了,==会让Activity/Fragment越来越臃肿==。

MVP

简介

于是大家都觉得MVC套在Android上不好。VC的代码会越来越多,如果要处理复杂的逻辑,Activity的代码上千上行。于是大家开始剥离VC里的代码。

这个用起来爽了很多,Activity的代码量也没这么多了。

大量的逻辑代码抽取到了Presenter层。

怎么调用逻辑层的方法呢?

View层持有Presenter层的引用或者通过管理类管理Presenter,总之View可以直接拿到Presenter,这样子,View就可以调用Presenter里的方法了。比如说Presenter你给我获取一个这个页面的分类

Presenter层如何更新UI呢

当View层去获取/创建Presenter的时候,把接口给到Presenter,比如说Presenter层获取到分类以后,通过接口更新UI即可。

mvp.png

优点

剥离了View和Controller,解决了复杂的业务Activity过于庞大的问题

缺点

假如我们去请求一个数据,这个时候请求是耗时的,数据回来了,可是界面已经被用户关掉了,数据回来以后,我们得判断UI控件是否还存在。

demo

View层

/**
 * V层 负责交互、显示
 */
class RegisterActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var phoneET: EditText
    private lateinit var pwdET: EditText
    private lateinit var registerBtn: Button

    //持有presenter层
    private lateinit var mPresenter: RegisterPresenter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_register)

        mPresenter = RegisterPresenter(this)
        phoneET = findViewById(R.id.phoneET)
        pwdET = findViewById(R.id.pwdET)
        registerBtn = findViewById(R.id.registerBtn)
        registerBtn.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        if (v.id == R.id.registerBtn) {
            //通过中间层 请求数据
            mPresenter.regist(
                phoneET.text.toString(),
                pwdET.text.toString()
            )
        }
    }

    fun showMessage(message:String){
        Toast.makeText(this, "$message", Toast.LENGTH_SHORT).show()
    }

}

presenter 层

/**
 * 中间层-
 * 1、抽离Ativity中的逻辑代码
 * 2、请求数据
 */
class RegisterPresenter {
    //持有model层
    private lateinit var mRegisterModel: RegisterModel
    private lateinit var mActivity: RegisterActivity
    //持有View层 一般用接口
    constructor(activity: RegisterActivity){
        mActivity = activity
        mRegisterModel = RegisterModel()
    }
    fun regist(phone:String,pwd:String) {
        MainScope().launch {
            mRegisterModel.regist(phone,pwd){
                //更新UI
                if(it){
                    mActivity.showMessage("登录成功")
                }else{
                    mActivity.showMessage("登录失败")
                }
            }
        }

    }

}

Model层

/**
 * 数据层 - 请求数据
 * 1.数据库
 * 2.网络
 * 3.其他app
 */
class RegisterModel {
    //不需要持有view、presenter层  通过回调将数据传给presenter层
    suspend fun regist(phone: String, pwd: String,response:(Boolean)->Unit) {
            delay(2000)
            response.invoke(Random.nextBoolean())
    }
}
上一篇 下一篇

猜你喜欢

热点阅读