MVVM与Android架构组件

5
我正在研究新的Android Architecture Components,并希望将其实现到Android应用程序中。我熟悉MVVM,因为我在iOS开发中使用这种范例。通过阅读谷歌提供的Android Architecture Components指南:https://developer.android.com/topic/libraries/architecture/guide.html,我只有几个问题...
在上述指南中,谷歌使用了UserRepository类来访问这些Web服务API-他们继续将此类设置为Singleton,如果仅有一个屏幕需要从REST API获取数据,那么这可能没问题。
我的担忧是:这似乎意味着Google主张根据ViewModel的基础创建存储库类。这对我来说听起来很不妥,在应用程序中有如此多的单例类。如果我们有10个屏幕,每个屏幕都需要自己的Repository module - 那么我们就有了10个单例对象。从iOS开发者的角度来看,这是不正确的。
解决方法是,创建一个中介(Repository)类,该类具有公共方法,暴露从REST API获取数据的API。Web服务部分将在其自己的类中。通过这种方式,我们可以得到良好的关注点分离。
是将每个ViewModel拥有一个repository类最佳实践,还是整个应用程序只有一个repository类?我不确定。
最后,在使用Room时也存在同样的问题-谷歌是否在说我们要根据ViewModel创建一个数据库,还是在整个应用程序中只有一个数据库?

你对一个简单页面和一个琐碎的例子过于深入地阅读了。他们设置的架构对一些应用程序可以很好地工作,但对其他应用程序则不然。多为自己考虑什么是有意义的,少复制粘贴指南。 - Gabe Sechan
意图并不是复制粘贴。但我理解你的观点。谢谢。 - Robert J. Clegg
1个回答

3
我认为架构指南并未建议为每个ViewModel创建单独的存储库类。在Google展示的示例中,使用了一个名为Dagger的库将单例存储库类注入到ViewModel中。通常最好按功能拆分存储库(或管理器)。例如,UserRepository负责所有与用户相关的API调用。
如果将此存储库转换为可注入任何ViewModel的单例,则任何ViewModel现在都可以访问该特定存储库。
快速查看Room后,我发现了这个小片段(link):
注意:在实例化AppDatabase对象时,应遵循单例设计模式,因为每个RoomDatabase实例相当昂贵,而且您很少需要访问多个实例。
对我来说,这意味着您可以以与使用存储库类相同的方式实现RoomDatabase。只需将它们作为单例注入到您的ViewModel中,这样您就不需要多个相同数据库的实例。

谢谢提供信息,确实很有道理。接下来,假设我们的应用程序中有许多不同的REST API - 没有两个API提供相同类型的数据。那么,将这些API按功能分组并将它们放入相关的存储库中是否是最好的选择呢?我想,对于Room DB也可以这样说。比如说,应用程序访问天气API和最新的赛车API - 不相关的数据 - 因此它们需要单独的ViewModels。在这种情况下,我们是否需要两个Room DB和两个存储库? - Robert J. Clegg
1
对于第一个场景,两个不同的REST API,您可能会查看数据而不是实际端点。您希望ViewModels对数据源保持不可知状态,所有ViewModels想要做的就是说; weatherRepo.getWeather()或类似的内容。如果您有一个获取来自不同端点的相关数据的不同数据源,则应将其放在同一个repo中。如果是不同的数据,则应将其放在不同的repo中。这不是关于来源,而是关于数据类型。 - Tim Kranen
@Tander 第二种情况并不是很现实,为什么要有两个完全独立的本地数据库呢?我会将它们合并到同一个房间数据库中(当然要正确设置关系)。 - Tim Kranen
关于不看终点,更重要的是数据类型这一点,真的为我解决了疑惑,谢谢。你说得对,ViewModel 不应该知道也不关心它获取的数据是来自 REST API 还是数据缓存,所以 repo 在那里是完美的。至于第二个用例;我同意似乎没有必要有多个数据库。我们宁愿有一个单例 Room 数据库,可以保存关于朋友列表和当前天气(两种不相关的数据类型)的数据。 - Robert J. Clegg
@Tander 没问题!如果答案是正确的,你可以选择接受它;) 另一个提示是,架构组件还不完全支持数据绑定,所以在那方面可能会遇到一些问题。 - Tim Kranen
作为一个相对新手的Android开发者,我并不完全了解数据绑定是什么。我需要进一步研究,感谢您的提醒。如果这种方法行不通,我想一个很好的备选方案是使用MVVM和RxJava(不使用App组件),现在暂时放弃持久性(因为这不是我的最大关注点)。再次感谢您的帮助。 - Robert J. Clegg

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