如何在 android 应用程序中实现 MVP 被动视图?

How to implement MVP Passive View in an android application?

我最近开始构建一个 android 应用程序,我想从头开始使用设计模式。有人告诉我 MVP (Model-View-Presenter) 是 android 应用程序的一个很好的模式。

我想知道是否可以实施 MVP 模式的 "Passive View" 变体?如果可以的话,我会展示任何代码……但现在我不知道被动视图在 android 应用程序中应该是什么样子。另外..在被动视图场景中扮演 MainActivity 的角色是什么?

如果有任何关于如何实现被动视图的解释、教程或示例,我将不胜感激。

使用 MVP 并不难

首先,在模型包中,您将存储所有类型的 POJO 类,它们具有 setter、getter 和应用程序的所有数据结构

然后是演示者,您可以在其中绑定此对象并对其执行一些逻辑。

在您对 Presenter 执行所有逻辑后,它会将所有信息传递给 View,因此之后您的 MainActivity(在本例中为视图)将只有几行代码,而且您的代码看起来非常真实有条理。

至于被动视图,这意味着您拥有代码更少的视图,可以在将来 运行 测试并拥有可维护的代码。

你可以使用 MVC、MVP、MVVM,但如果你想开始,我建议你从 MVP 开始

看看这张 MVP 的照片

您还可以查看 THIS MVP 教程

Android 中的 MVP 模式建议您的视图 classes(片段、活动)不包含任何表示或业务逻辑,但所有逻辑都委托给 Presenter class.当 View 初始化、事件发生或 View 被销毁时,Presenter 通常依次调用 View 提供的 void 方法。

想象一下实现以下接口的 View 和 Presenter:

public interface Contract {

    interface View {

        void initView();

        void setTextColor();

    }

    interface Presenter {

        void init();

        void onButtonClicked();

    }
} 

在我们的简单示例中,View 将初始化 Presenter(依赖注入超出此 post 的范围),然后调用 Presenter 的 initView 方法。 Presenter 将负责所有初始化逻辑,例如从网络/存储中获取数据,并在需要时更新 View。当用户依次单击按钮时,View 将通过调用 Presenter 的 onButtonClicked() 方法将操作委托给 Presenter。 Presenter 可以进行一些处理,并根据结果调用 View 的 setTextColor() 方法。

使用 MVP 的最重要原因是能够使用 Junit 和 Mockito 等模拟框架测试您的逻辑。您的 Presenter 应该用纯 Java 或 Kotlin 编写,不依赖于 Android 框架库。然后您可以使用 JVM 测试您的 Presenter,而不必连接设备。这都是Bob叔叔的clean architecture guidelines的一部分。

获得 MVP 的两个最佳资源是 Antonio Leiva 的博客 post and Google's architecture samples in github

感觉这里对主持人有一个致命的误解。尽管 MVP 是通用标准,但大多数人认为 Presenter 是 Controller,或者更糟的是 Controller、Repositories、Gateways 的混合体。

演示者应该做一件事:演示。这应该是它的唯一目的。许多人不知不觉地实现了一个 MVC 架构,称之为 MVP,限制数据流如下:View <-> Controller / Presenter <-> Model.. 现在这个模式没有错,因为它分离了你的系统层,如果操作正确。您应该能够将您的域和数据层(Android 开发人员通常将这些层称为 Presenter 和 Model 层)交换到另一个系统,并且代码应该仍然可以工作而没有任何依赖性问题。要实现这一点,您必须避免任何会导致绑定到所谓的细节(UI、数据库、框架、硬件、浏览器,OS)的依赖项。现在说到层,我们通常有这样的数据流层次结构:UI -> 域 -> 数据,在 Android 应用程序中,我们会将所有 UI 代码放入 UI 组件。现在有 2 个选项来定位演示者:您可以通过为演示者特定视图引入接口来抽象视图。避免演示器中的任何 android / 硬件特定依赖项(如上下文)。如果你实现了这一点,那么你可以说,你的 Presenter 属于你的 Domain 层。如果您的 Presenter 知道任何 Android 细节(或者更糟的是数据库),那么您会自动将其放入视图层(如果您尝试从中访问数据库,甚至会破坏您的体系结构)。 现在让我们假设你抽象了你的 View 并且让你的 Presenter 成为一个 Domain 对象。您的 Presenter 不再关心其代表 View 的实际实现,它有自己的抽象并且知道将值传递到哪里。无论是移动、网络还是嵌入式应用程序都不再重要。 现在 Presenter 如何从数据层接收数据并用数据填充 UI?我们使用与视图相同的技术:抽象。 我们将创建存储库、网关、数据服务的接口/抽象 class,或者您希望调用 data/model 层的接口。您将拥有 POJO、您的数据访问逻辑、缓存等。请注意,到目前为止,我们正在使用 POJO!我们不依赖于任何平台绑定细节(如上所述)。但由于我们现在需要做一些缓存,我们必须使用来自 Android(或 Room)的 SQLite 管理器。这该怎么做?抽象。抽象任何导致您的代码绑定到任何平台的细节。

您可以在下面看到 Bob 叔叔提出的实体软件架构设计的图片。内层不应该知道外层。 这张图反映了我刚刚在这里描述的开发技术,这与 Bob 大叔的书中描述的技术相同。我们通过使用它们的抽象来避免对细节的任何依赖。真正的实现(活动、片段、SQLiteDatabase)正在通过依赖注入从外部“连接”到内层。 这种技术也称为依赖倒置。

我建议您阅读 Robert C. Martin 的《清洁架构》一书,以加深对它的理解。