为什么在Android的MVP模式中应该使用接口?

6

我第一次使用Kotlin制作一个Android应用程序,使用MVP模式。我的问题是:既然Kotlin提供了高阶函数,我们为什么需要View和Presenter接口来进行通信?难道我们不能只使用这些高阶函数吗?没有接口使用模式是否不好?

我已经查看并阅读了大量的文章和教程,但它们都没有回答我的问题。下面的代码中我所做的是错误的吗?有人能够向我解释一下吗?

在我的Activity中:

override fun init() {

    btn_login.setOnClickListener {
        LoginPresenter.userLogin(et_emailAddress.text.toString(),et_password.text.toString()){
            if (it){
                //do something
            }else{
                //do something
            }
        }
    }
}

我的演讲者
object LoginPresenter {

fun userLogin(emailId: String, password: String, completion: (Boolean) -> Unit) {
    //do something
    completion(true)
 }
}

3
"为什么我需要为View和Presenter使用接口?" - 你不一定需要使用接口,但最好编程使用抽象而不是具体实现。想想在单元测试中如何受益,或者当你更改实现时 - 合同保持不变。我认为对于Presenter而言,使用接口没有任何好处,只有对于视图才有。另外,观察到你的Presenter是一个单例,它真正应该被作用域限制在Activity中。关于使用高阶函数的论据存在疑问,因为你可以在Java中提供Consumer<T>。此外,这会破坏MVP流程控制。 - Mark
2个回答

2
  1. 高阶函数的代价

    Kotlin官方文档关于高阶函数的代价

    使用高阶函数会带来一定的运行时代价:每个函数都是一个对象,它捕获了闭包,即在函数体中访问的那些变量。内存分配(用于函数对象和类)和虚拟调用引入了运行时开销。

    如果你把所有接口都替换成高阶函数,可能会导致性能不佳。

2. 接口可以容纳多个函数,在使用高阶函数时需要单独的函数参数。 考虑以下情况,

interface UserLoginInterface {
      fun onLoginSuccess(loggedInUser: User)
      fun onLoginFailure(error: ErrorResponse)
      fun onRedirect(someOtherObjectWithDirectives: SomeDataClass)
 }

为了将此转换为高阶函数用法,您需要使用三个 Function 参数。最初的回答中提到了这一点。

不知道使用高阶函数会导致性能问题。谢谢。 - Mandip Giri

1
这在软件开发中相当普遍。虽然您可能不使用接口,但接口有许多优点。以下是其中一些:
1. 使用接口可以拥有多个实现而不必关心具体实现的类型。在使用LoginPresenter.userLogin() 方法时,高阶函数限制了该方法仅适用于 LoginPresenter 类型。
2. 大多数设计模式都是基于将接口与其实现分离的原则。因此,编程到实现而非抽象将无法利用它们。
3. 如果依赖其他实现,则无法正确地对类进行单元测试,因为在这种情况下无法进行模拟。
4. 具体实现的代码维护和扩展变得更加困难。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接