通常使用 Java,我们制作一个 *Contract
接口(interface)来处理 View 和 Presenter 之间的交互,例如:
主 Activity
作为 View
public class MainActivity extends Activity implements MainContract {
@Override
public void onCreate(Bundle b) {
presenter.requestData();
}
@Override
public void showData(String data) {
// Handle data ...
}
主讲人
作为演示者
public class MainPresenter {
public void requestData() {
contract.showData("data");
}
}
主合约
作为接口(interface)
public interface MainContract {
void showData(String data);
}
既然 Kotlin 具有“高阶函数”的特性,我们是否应该简单地传递函数来处理 View 和呈现器之间的交互?它可以是这样的:
查看:
presenter.requestData { data ->
// Handle data
}
主持人:
fun requestData(handler: (String) -> Unit) {
handler("data")
}
我不是在问可能性,我是在问这是否是最佳实践。
最佳答案
这个问题的答案更多的是相关的架构决策,而不是技术限制。您可以使用匿名实例在 Java 中(甚至在 Java7 中)实现同样的事情(假设它会有更多的样板文件并且更难阅读)。
在 MVP 中拥有 View 实现的契约(Contract)的想法是每个演示者都知道如何获取、操作和呈现所述契约(Contract)。潜在的 View 可以实现多个契约并有多个演示者。此外,每个演示者实例仅适用于契约(Contract)的一种实现,但您可以有两个实例服务于两种不同的实现。
如果不是每个 View 都符合每个演示者的契约(Contract),而是演示者的每次调用都采用 lambda,您迟早会遇到问题。
例如,想象一个异步获取数据并将其缓存在内存中的呈现器:
- View 调用呈现器方法
fetchData()
。 - 演示者调用合约的
showLoading()
方法。 - (一段时间过去了)
- 演示者调用合约的
hideLoading()
和showData(data)
方法。 - 用户再次交互并触发
fetchData()
- 演示者使用缓存数据调用
showData()
在这种情况下,如果我们使用 lambda 而不是契约,我们将需要在同一方法中请求两个不同的 lambda:一个用于缓存,一个用于缓存。 我们也正在将 View 实现耦合到呈现器,将来呈现器接口(interface)的另一个实现可能不需要这两个 lambda,因为逻辑已经改变。
重要的是要记住,在理想情况下,在 MVP 中, View 和呈现器都通过接口(interface)相互通信,在这种情况下,呈现器接口(interface)不应受到实现细节的影响,而应仅公开它们能够执行的操作。
关于android - 在 MVP 中使用 Kotlin 高阶函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55304960/