使用 MVVM 和 Clean Architecture 构建 Android 应用程序

在 Android 开发领域,设计一个健壮且可维护的架构至关重要。模型-视图-视图模型 (MVVM) 和清洁架构这两种流行的架构模式提供了构建 Android 应用程序的结构化方法。在本文中,我们将探索如何结合这两种模式来创建可扩展和可测试的 Android 应用程序。

在这里插入图片描述
1.了解 MVVM:模型-视图-视图模型 (MVVM) 模式将数据管理、UI 呈现和用户交互的关注点分开。它由以下组件组成:

  • 模型:代表应用程序的数据和业务逻辑。

  • 视图:显示 UI 元素并与用户交互。

  • ViewModel:介于模型和视图之间,为 UI 提供数据并处理用户操作。
    2.MVVM 的优点:MVVM 提供了几个优点,包括:

  • 关注点分离:UI逻辑和业务逻辑的分离增强了可维护性。

  • 可测试性:ViewModel 和 Model 类可以很容易地进行单元测试,而不依赖于 Android 框架。

  • 生命周期感知:MVVM 利用 LiveData 或 RxJava 来处理数据更新和生命周期事件。
    3.理解Clean Architecture:Clean Architecture强调关注点分离和依赖倒置。它由三层组成:

在这里插入图片描述

  • 表示层:处理与 UI 相关的任务并与 ViewModel 交互。
  • 领域层:包含独立于框架的业务逻辑和用例。
  • 数据层:管理数据检索和存储,包括本地和远程数据源。

4.Combining MVVM with Clean Architecture:要在 Android 中将 MVVM 与 Clean Architecture 结合起来,我们可以遵循以下准则:

  • UI层:实现MVVM的View和ViewModel组件。View 观察 ViewModel 提供的 LiveData 或 RxJava 流。
  • 表示层:创建处理 UI 相关任务并与领域层通信的 ViewModel 类。
  • 领域层:定义独立于 Android 框架的用例和业务逻辑。使用接口来解耦层。
  • 数据层:实现抽象数据源(本地数据库、远程 API)的存储库。使用依赖倒置使领域层独立于具体实现。

在这里插入图片描述

在这里插入图片描述
5. MVVM with Clean Architecture 的好处:通过将 MVVM 与 Clean Architecture 相结合,我们可以实现以下好处:

  • 关注点分离:每一层都有不同的职责,提高了可维护性和模块化。
  • 可测试性:业务逻辑和用例可以独立于 UI 进行测试,从而产生更可靠的代码。
  • 可扩展性:该架构允许在不影响其他层的情况下轻松扩展和修改。
  • 可复用性:领域层是独立于框架的,可以在不同的平台上复用。

6.在 Android 中使用 Clean Architecture 实现 MVVM:提供有关如何在 Android 项目中使用 Clean Architecture 实现 MVVM 的分步说明。包括每个层的代码片段、最佳实践和推荐的库(例如,LiveData、Room、Retrofit)。

7.结论:MVVM with Clean Architecture 提供了一种强大的方法来构建模块化、可测试和可维护的 Android 应用程序。通过分离关注点并利用每种模式的优势,开发人员可以创建易于扩展和调整的强大应用程序。

结束语:理解 MVVM 模式和 Clean Architecture 对于寻求构建高质量应用程序的 Android 开发人员来说至关重要。通过组合这些模式,开发人员可以利用两者的优势并创建结构良好、可扩展且可维护的 Android 应用程序。

当然!下面是一些例子来说明在 Android 中使用 Clean Architecture 的 MVVM 的实现:

UI 层(View 和 ViewModel):在 UI 层中,您通常会将活动或片段作为视图和相应的 ViewModel 类。这是一个简单的登录屏幕示例:

// LoginActivity.kt (View) 
class  LoginActivity : AppCompatActivity () { 
    private  lateinit  var viewModel: LoginViewModel 

    override  fun  onCreate (savedInstanceState: Bundle ?) { 
        super .onCreate(savedInstanceState) 
        setContentView(R.layout.activity_login) 

        viewModel = ViewModelProvider( this ). get (LoginViewModel:: class .java) 

        // 从 ViewModel 观察 LiveData
         viewModel.getLoginResult().observe( this , { loginResult ->
            // 根据登录结果更新 UI 
            if (loginResult.success) { 
                // 导航到主屏幕
            } else { 
                // 显示错误消息
            } 
        }) 

        // 为登录按钮设置点击监听器
        loginButton.setOnClickListener { 
            val username = usernameEditText .text.toString() 
            val password = passwordEditText.text.toString() 
            viewModel.login(username, password) 
        } 
    } 
} 

// LoginViewModel.kt (ViewModel) 
class  LoginViewModel ( private  val loginUseCase: LoginUseCase) : ViewModel() {
    private  val loginResult = MutableLiveData<LoginResult>() 

    fun  getLoginResult () : LiveData<LoginResult> = loginResult 

    fun  login (username: String , password: String ) { 
        viewModelScope.launch { 
            val result = loginUseCase.login(username, password) 
            loginResult.值 = 结果
        } 
    } 
}

2.表示层:表示层充当 UI 层和领域层之间的中介。它包含 ViewModel 和任何与表示相关的逻辑。下面是一个简单的 LoginViewModel 示例:

// LoginViewModel.kt
类 LoginViewModel ( private  val loginUseCase: LoginUseCase) : ViewModel() { 
    private  val loginResult = MutableLiveData<LoginResult>() 

    fun  getLoginResult () : LiveData<LoginResult> = loginResult 

    fun  login (username: String , password: String ) { 
        viewModelScope.launch { 
            val result = loginUseCase.login(username, password) 
            loginResult.value = result 
        } 
    } 
}

3.领域层:领域层包含应用程序的业务逻辑和用例。它独立于 Android 框架。下面是一个 LoginUseCase 的例子:

// LoginUseCase.kt 
class  LoginUseCase ( private  val userRepository: UserRepository) { 
    suspend  fun  login (username: String , password: String ) : LoginResult { 
        // 执行业务逻辑和数据操作
        val user = userRepository.getUserByUsername(username) 

        return  if ( user != null && user.password == password) { 
            LoginResult(success = true , user) 
        } else { 
            LoginResult(success = false , error =“无效的用户名或密码” ) 
        } } 
    }

4.数据层:数据层处理数据检索和存储,与本地和远程数据源交互。下面是一个使用本地数据库的 UserRepository 示例:

// UserRepository.kt 
class  UserRepository ( private  val userDao: UserDao) { 
    suspend  fun  getUserByUsername (username: String ) : User? { 
        // 执行数据库查询或网络请求
        return userDao.getUserByUsername(username) 
    } 
}

5.依赖注入:要实现松散耦合和依赖倒置,可以使用依赖注入框架,如 Dagger 或 Koin。下面是一个使用 Dagger 进行依赖注入的例子:

// AppModule.kt 
@Module 
class  AppModule { 
    @Provides 
    fun  provideUserRepository (userDao: UserDao ) : UserRepository { 
        return UserRepository(userDao) 
    } 

    @Provides 
    fun  provideLoginUseCase (userRepository: UserRepository ) : LoginUseCase { 
        return LoginUseCase(userRepository) 
    } 
} 

// AppComponent .kt 
@Component(modules = [AppModule::class]) 
interface  AppComponent { 
    fun  inject (loginActivity: LoginActivity )
}

6.Application类:在Application类中,需要初始化依赖注入框架,提供必要的依赖。这是一个例子:

class  MyApp : Application () { 
    lateinit  var appComponent: AppComponent 

    override  fun  onCreate () { 
        super .onCreate() 
        appComponent = DaggerAppComponent.builder() 
            .appModule(AppModule()) 
            .build() 
    } 
}

确保更新 AndroidManifest.xml 文件以使用您的自定义应用程序类:

<application 
    android:name=".MyApp"“.MyApp”
     ... 
</application>

7.将它们放在一起:为了连接各层并完成架构,您需要在表示层、领域层和数据层之间建立连接。这是一个例子:

// LoginActivity.kt
类 LoginActivity : AppCompatActivity () { 
    @Inject 
    lateinit  var loginViewModelFactory: LoginViewModelFactory 

    private  lateinit  var viewModel: LoginViewModel 

    override  fun  onCreate (savedInstanceState: Bundle ?) { 
        super .onCreate(savedInstanceState) 
        setContentView(R.layout.activity_login) 

        (应用程序作为MyApp).appComponent.inject( this ) 

        viewModel = ViewModelProvider( this , loginViewModelFactory)
            . get (LoginViewModel:: class .java) 

        // ... 其余代码保持不变
    } 
} 

// LoginViewModelFactory.kt 
class  LoginViewModelFactory ( private  val loginUseCase: LoginUseCase) : 
    ViewModelProvider.Factory { 
    override  fun  <T : ViewModel?> 创建(modelClass: Class < T >) : T { 
        if (modelClass.isAssignableFrom(LoginViewModel:: class .java)) { 
            return LoginViewModel(loginUseCase) as T 
        } 
        throwIllegalArgumentException(“未知的 ViewModel 类”)
    } 
}

确保根据您的具体要求创建必要的数据库、DAO 和网络相关的类。

8.结论:通过遵循 MVVM with Clean Architecture 原则,您可以创建组织良好、可维护和可测试的 Android 应用程序。关注点的分离和层次的清晰划分使开发、调试和可扩展性更容易。

结束语:具有简洁架构的 MVVM 为构建健壮且可维护的 Android 应用程序提供了坚实的基础。通过组合这些模式,您可以实现关注点分离、可测试性和可伸缩性。通过对概念和实际示例的清晰理解,您现在已具备创建高质量 Android 应用程序的能力。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

猜你喜欢

转载自blog.csdn.net/Eqiqi/article/details/131116014