Android 如何在 MVP 架构中的两个演示者之间共享数据?
How to share data between two presenters in MVP architecture in Android?
这是一个示例场景:
我有一个 activity(视图)和该视图的演示者。演示者从网络 API 中获取用户列表,并使用 List 对象将其保存在内存中。 activity包含不同类型的片段来显示基于User.type的用户的内容。这两个片段(UserType1Fragment 和 UserType2Fragment)也有各自的演示者。
activity 的主持人决定接下来显示的片段类型(I 或 II)。片段的呈现器决定用户对象的显示方式并处理名为 killUser() 的按钮单击事件。这应该更新 activity 的演示者中的列表对象。
这就是问题所在:
fragment presents 如何引用 activity presenter 中的数据?演示者不应直接相互交流。也许我应该将列表抽象成 repository/interactor?列表将如何在演示者之间共享?
您可以通过片段的 newInstance() 将列表引用传递给片段。我认为主持人之间不应该直接交流。
所以我最终实现了@Jahnold 推荐的东西。 (我将 post 中的图表 link 提供一个想法 whosebug.com/a/41966497/568898 )
Hannes Dorfmann(created/manages 著名的 Mosby MVP 库的人:Github link)也向我指出了这个方向。
实施
我有一个主要 activity 的演示者和多个可以在 activity 中使用的片段。每个片段都有自己的演示者。然后我使用一个存储库(搜索存储库模式),它基本上存储模型和业务逻辑。对于我的用例,我将此存储库保持为单例。存储库以三种形式提供数据,来自在线 api、sqllite 数据库或存储在内存中的缓存(基本上是项目的数组列表)。我在这个存储库中也有一些 currentitem int 索引和东西,它们会根据当前状态进行更新。
因此,数据、状态和业务逻辑都存储在这个共享存储库中。主持人和观点都很愚蠢。我在演示者中没有太多业务逻辑(特定于应用程序的逻辑)。它们只是具有与必须如何显示数据相关的逻辑(查看特定逻辑)并在逻辑上对其进行预处理。
例子
当用户单击子片段中的按钮时,每当片段和 activity 需要相互交谈(通过演示者)时,片段要求其演示者处理点击,演示者更新存储库的 currentItemSelected 数据(或其他东西)并要求片段向 activity 实现的接口侦听器触发事件(比如 onbuttonclick)。当 activity 获取事件时,它要求它自己的演示者处理它,然后 activity 演示者在存储库中查找更新以获取新的 currentItemSelected。
额外信息(进阶版):
您还可以遵循 Clean 架构,这是一种更高级版本的 MVP 架构。 MVP 只处理视图的架构,而 Clean 架构还处理业务逻辑和数据架构,MVP 只是 clean arch 的一小部分,用于处理视图。使用它,您可以将我的案例中的大型存储库分解为处理特定业务逻辑用例的更多用例(或交互器),而存储库仅提供数据。所以现在的逻辑流程是视图-->演示者-->交互器-->回购然后返回。
这是一个示例场景:
我有一个 activity(视图)和该视图的演示者。演示者从网络 API 中获取用户列表,并使用 List 对象将其保存在内存中。 activity包含不同类型的片段来显示基于User.type的用户的内容。这两个片段(UserType1Fragment 和 UserType2Fragment)也有各自的演示者。
activity 的主持人决定接下来显示的片段类型(I 或 II)。片段的呈现器决定用户对象的显示方式并处理名为 killUser() 的按钮单击事件。这应该更新 activity 的演示者中的列表对象。
这就是问题所在:
fragment presents 如何引用 activity presenter 中的数据?演示者不应直接相互交流。也许我应该将列表抽象成 repository/interactor?列表将如何在演示者之间共享?
您可以通过片段的 newInstance() 将列表引用传递给片段。我认为主持人之间不应该直接交流。
所以我最终实现了@Jahnold 推荐的东西。 (我将 post 中的图表 link 提供一个想法 whosebug.com/a/41966497/568898 )
Hannes Dorfmann(created/manages 著名的 Mosby MVP 库的人:Github link)也向我指出了这个方向。
实施
我有一个主要 activity 的演示者和多个可以在 activity 中使用的片段。每个片段都有自己的演示者。然后我使用一个存储库(搜索存储库模式),它基本上存储模型和业务逻辑。对于我的用例,我将此存储库保持为单例。存储库以三种形式提供数据,来自在线 api、sqllite 数据库或存储在内存中的缓存(基本上是项目的数组列表)。我在这个存储库中也有一些 currentitem int 索引和东西,它们会根据当前状态进行更新。
因此,数据、状态和业务逻辑都存储在这个共享存储库中。主持人和观点都很愚蠢。我在演示者中没有太多业务逻辑(特定于应用程序的逻辑)。它们只是具有与必须如何显示数据相关的逻辑(查看特定逻辑)并在逻辑上对其进行预处理。
例子
当用户单击子片段中的按钮时,每当片段和 activity 需要相互交谈(通过演示者)时,片段要求其演示者处理点击,演示者更新存储库的 currentItemSelected 数据(或其他东西)并要求片段向 activity 实现的接口侦听器触发事件(比如 onbuttonclick)。当 activity 获取事件时,它要求它自己的演示者处理它,然后 activity 演示者在存储库中查找更新以获取新的 currentItemSelected。
额外信息(进阶版):
您还可以遵循 Clean 架构,这是一种更高级版本的 MVP 架构。 MVP 只处理视图的架构,而 Clean 架构还处理业务逻辑和数据架构,MVP 只是 clean arch 的一小部分,用于处理视图。使用它,您可以将我的案例中的大型存储库分解为处理特定业务逻辑用例的更多用例(或交互器),而存储库仅提供数据。所以现在的逻辑流程是视图-->演示者-->交互器-->回购然后返回。