前言
最近实习写mvvm比较多,但是好多老项目都是mvp,准备接下来写一个mvp模式的demo练手,在此之前做一个复习。
mvp在mvc模式的基础上发展而来,原来的Controller是Activity,但是还view,高度耦合。具体可以看我的上一篇博客。
Android安卓MVC模式复习
如有兴趣,还可以看下面的MVVM模式链接
Android MVVM架构学习
基本概念
mvp把Controller改成了Presenter,Activity也变成了view层。
View与Model并不直接交互,而是使用Presenter作为View与Model之间的桥梁。
View 对应于Activity,负责View的绘制以及与用户交互
Model 依然是业务逻辑和实体模型
Presenter 负责完成View于Model间的交互
实现核心原理:
其中Presenter中同时持有View层的Interface的引用以及Model层的引用,而View层持有Presenter层引用。
当View层某个界面需要展示某些数据的时候,首先会调用Presenter层的引用,然后Presenter层会调用Model层请求数据,当Model层数据加载成功之后会调用Presenter层的回调方法通知Presenter层数据加载情况,最后Presenter层再调用View层的接口将加载后的数据展示给用户。
代码示例
我们还是以登录页面为例。
下面是我的代码架构:
Model层
1.User bean类,
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 22: 08
* @Description: 实体bean
*/
data class User(
val username: String,
val password: String
)
2.接口,表示要实现的业务逻辑,这里是登录
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 22: 20
* @Description: 接口
*/
interface LoginModel {
fun login(user: User, listener: OnLoginListener)
}
3.接口实现类,具体登录实现方法,以及回调给Presenter结构,这里是一个结果监听
class LoginModelImpl: LoginModel {
override fun login(user: User, listener: OnLoginListener) {
if (user.username.equals("tian") && user.password.equals("qaq")){
listener.onSuccess()
}else{
listener.onFailure()
}
Log.d("tian","${user.username}")
}
}
Presenter层
1.接口
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 22: 29
* @Description: 接口实现类,具体业务逻辑
*/
interface LoginPresenter {
fun loginBridge()
}
2.接口实现类,连接view层和model层
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 23: 11
* @Description: 描述
*/
class LoginPresenterImpl(
private val loginView: LoginView
): LoginPresenter,OnLoginListener{
private val loginModel: LoginModel = LoginModelImpl()
override fun loginBridge() {
val user = loginView.getUser()
loginModel.login(user = user,this)
}
override fun onFailure() {
loginView.showFailure()
}
override fun onSuccess() {
loginView.showSuccess()
}
}
3.listener,给model回调
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 22: 25
* @Description:是presenter层的接口,
* 方便实现回调presenter,通知presenter业务逻辑的返回结果
*/
interface OnLoginListener {
fun onFailure()
fun onSuccess()
}
View层
1.接口
/**
* @Author: tian7
* @Email: 253493510@qq.com
* @Date: on 2024/6/27: 23: 02
* @Description: 描述
*/
interface LoginView {
fun getUser(): User
fun showFailure()
fun showSuccess()
}
2.Activity
class MvpActivity : AppCompatActivity(), LoginView{
private lateinit var ed_username: EditText
private lateinit var ed_password: EditText
private lateinit var btn_login: Button
private lateinit var loginPresenter: LoginPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mvp)
ed_username = findViewById(R.id.et_username)
ed_password = findViewById(R.id.et_password)
btn_login = findViewById(R.id.btn_login)
loginPresenter = LoginPresenterImpl(this)
btn_login.setOnClickListener{
loginPresenter.loginBridge()
}
}
override fun getUser(): User {
return User(ed_username.text.toString(),ed_password.text.toString())
}
override fun showFailure() {
Toast.makeText(
this,
"用户名或密码错误",
Toast.LENGTH_SHORT
).show()
}
override fun showSuccess() {
Toast.makeText(
this,
"登录成功",
Toast.LENGTH_SHORT
).show()
}
}
显示
优缺点
优点:降低了耦合度,presenter可以复用
缺点:业务逻辑复杂的话,接口太多,维护困难,再就是持有view(Activity)强引用,可能内存泄漏。这块解决方法我没有进行过多的了解,欢迎补充。
参考
https://blog.csdn.net/hdhhd/article/details/123204173