在 Android MVP 中,演示者应该 return 一个值吗?

In Android MVP, should a presenter return a value?

我正在尝试学习 MVP,我有一些问题想请教,presenter 应该 return 一个值吗?

像这样:

class MainPresenter : BasePresenter<MainContract.View>(), MainContract.Actions {
    override fun getProducts (id: Int): List<Product> {
        //...
        return products
    }
}

interface MainContract {
    interface Actions {
        fun getProducts(id: Int): List<Product>
    }
}

或者像这样:

class MainPresenter : BasePresenter<MainContract.View>(), MainContract.Actions {
    override fun getProducts (id: Int) {
        //...
        mvpView?.showProducts(products)
    }
}

interface MainContract {
    interface Actions {
        fun getProducts(id: Int)
    }

    interface View{
        fun showProducts(products: List<Product>)
    }
}

我们要问的第一个问题是,主持人应该向谁展示return价值?谁对演讲者价值观感兴趣?我们是否想将我们的业务逻辑与视图层混为一谈?鉴于我们的业务逻辑在呈现器本身内部,还有谁对任何数据感兴趣?

这绝对不是我们的意图,并且会转移对 MVP 的注意力。 我们需要通过接口传播值,通常是视图层方法,并将它们作为参数传递给驻留在视图层中的其他相关方。

TL;DR: 选项 #2

这是一个自以为是的答案,但我通常会尝试向演示者注入某种抽象的 view 参考。基本上,一个界面,其中的实际实现可以是 activity、片段或视图,但对于演示者而言,这无关紧要。它所知道的只是界面呈现的合同。

我倾向于不 return 来自我的演示者的价值观。我会在演示者中注入另一个抽象来获取产品。我们通常称他们为交互者。它的职责是在后台线程上从存储库中获取数据并在主线程上传递结果。回调的经典方式如下所示(但您应该考虑改用 kotlin 协程,这样可以避免回调):

class MainPresenter(val interactor: MainInteractor) : BasePresenter<MainContract.View>(), MainContract.Actions, MainContract.Interactor.Callback {
    override fun getProduct (id: Int) {
        //...
        interactor.getProduct(product, this) // this is the callback
    }

    override fun onResult(result: Product) {
        mvpView?.showProduct(result)
    }
}

interface MainContract {
    interface Interactor {
        interface Callback<T> { fun onResult(result: T) }
        fun getProduct(id: Int, listener: Callback<Product>)
    }

    interface View{
        fun showProduct(product: Product)
    }
}