软件设计中的接口隔离

6 阅读2分钟

软件设计中的接口隔离

在软件设计的过程中,特别是在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生效?这是什么道理?

  1. 多态:在Java/Kotlin中,父类引用可以指向子类对象。当ViewModel通过UserDataRepository接口类型调用setTopicIdFollowed方法时,实际上调用的是子类OfflineFirstUserDataRepository中重写的方法。

这是一个和语言特性相关的提问。通过依赖注入,ViewModel中持有的UserDataRepository实例实际上是由依赖注入框架(如Hilt)提供的OfflineFirstUserDataRepository对象。这是基于面向对象编程中的多态特性。

  1. 接口隔离原则:这里也体现了接口隔离原则,ViewModel只依赖于UserDataRepository接口,而不依赖于具体的实现。这样便于测试和替换不同的实现。

  2. 依赖注入:在NowInAndroid项目中,使用了依赖注入(可能是Hilt)来管理依赖关系。当ViewModel需要UserDataRepository时,注入的实际上是它的实现类OfflineFirstUserDataRepository的实例。这是因为在依赖注入的设置中,将UserDataRepository绑定到了OfflineFirstUserDataRepository。