软件设计中的接口隔离
在软件设计的过程中,特别是在Android的开发里,
往往在业务上的处理,不希望将业务和UI、viewModel耦合,
因此,viewModel中对于数据的来源,可以使用接口隔离的方式,
将当前UI的数据来源统一管理,
接口的实现类,则是具体的数据来源的处理操作,
viewModel需要数据时,只需要调用接口方法就行。
而不需要考虑接口实现的子类中的具体实现。
看NowInAndroid中的使用
//在NowInAndroid谷歌项目中,关于接口隔离的使用,
viewModel:
userDataRepository.setTopicIdFollowed(followedTopicId, followed)//传入参数,获取源数据
interface UserDataRepository:
/**
* Sets the user's newly followed/unfollowed topic
*/
suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean)
OfflineFirstUserDataRepository:UserDataRepository
override suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean) {
niaPreferencesDataSource.setTopicIdFollowed(followedTopicId, followed)
analyticsHelper.logTopicFollowToggled(followedTopicId, followed)
}
我想问的是,为什么在viewModel里只需要用UserDataRepository的实例调用setTopicIdFollowed,就能够让OfflineFirstUserDataRepository的setTopicIdFollowed生效?这是什么道理?
- 多态:在Java/Kotlin中,父类引用可以指向子类对象。当ViewModel通过UserDataRepository接口类型调用setTopicIdFollowed方法时,实际上调用的是子类OfflineFirstUserDataRepository中重写的方法。
这是一个和语言特性相关的提问。通过依赖注入,ViewModel中持有的UserDataRepository实例实际上是由依赖注入框架(如Hilt)提供的OfflineFirstUserDataRepository对象。这是基于面向对象编程中的多态特性。
-
接口隔离原则:这里也体现了接口隔离原则,ViewModel只依赖于UserDataRepository接口,而不依赖于具体的实现。这样便于测试和替换不同的实现。
-
依赖注入:在NowInAndroid项目中,使用了依赖注入(可能是Hilt)来管理依赖关系。当ViewModel需要UserDataRepository时,注入的实际上是它的实现类OfflineFirstUserDataRepository的实例。这是因为在依赖注入的设置中,将UserDataRepository绑定到了OfflineFirstUserDataRepository。