Kotlin多平台最佳架构指南
在这篇文章中,我们将对 Kotlin 多平台移动端的最佳架构进行深入探讨。在2023年,作为 Android 开发者,我们会倾向于采用 MVVM 架构,因为它简单、灵活且易于测试。而作为 iOS 开发者,我们可能会选择 MVC、Viper 等架构。在 Flutter 世界中,BLoC(Business logic components)是非常流行的架构。
Kotlin 多平台提供了跨平台开发,支持在 iOS、Android 或桌面应用中共享业务逻辑和表示逻辑。在这里,我们将进一步讨论应该遵循哪种架构,并寻找适合 KMM 的架构。
我们想要实现什么?
在架构方面,没有明确的矩阵来决定应该采用哪种架构。在 KMM 的世界里,架构应该足够灵活,能够适应对现有代码的新变更,并在可测试性和可维护性方面支持多个平台。
简单性是成功架构的关键。我们将避免使用繁琐的代码,追求简单性。
以下是一些关键要点:
- 最大程度地共享代码,无论是业务逻辑还是表示逻辑。
- 最小化平台特定的代码。
- 便于本地和共享逻辑之间的交流。
- 灵活适应未来的修改。
- 遵循 SOLID 原则。
BLoC 架构
BLoC 表示基于业务逻辑组件的架构,在 Flutter 世界中非常流行。让我们将其分解成较小的部分,并尝试理解其矩阵。
业务逻辑组件
在 BLoC 中,业务逻辑组件是一个简单的组件,负责处理业务逻辑。它涉及对事件的响应,通过对事件的响应来修改状态的更改。为了理解这一点,让我们创建一个简单的组件并尝试实现业务逻辑。
//GalleryComponent.kt
interface GalleryComponent {val model: Modelfun onGalleryClick()fun onDeleteClick()data class Model(val isLoading: Boolean)
}
//GalleryFeature.kt
class GalleryFeature(): GalleryComponent {override val model: Model get() = Model()override fun onGalleryClick() {//handle click here}override fun onDeleteClick() {//handle click here}
}
这不是一个典型的 BLoC 架构,如果您仔细查看GalleryComponent.kt
或这些类,会发现 BLoC 还涉及状态、事件和消费者组件等。
我们希望保持简单,不涉及在 Kotlin 多平台中可以轻松避免的其他组件。如果您熟悉 MVVM 架构,将 BLoC 架构中的 ViewModel
替换为组件,那么它与 MVVM 架构非常相似。
通过观察其可测试性、灵活性和简单性,BLoC 架构也适用于 KMM 的世界。
事实上,BLoC 在 KMM 中带来了使用挑战,因为大多数开发人员来自 Android 和 iOS 的世界。他们更喜欢在 MVVM 上工作,而不是采用新的 BLoC 模式,尽管其行为与 MVVM 类似。如果您想尝试 BLoC 模式,我建议您不要使用任何复杂的架构库,因为这样会很难维护整体架构。
MVI 架构
MVI(Model-View-Intent)
架构使用意图将业务逻辑和表示逻辑分离。在 MVI 中,意图用于与业务逻辑进行通信。
在此,意图从视图接收,模型通过对意图的响应进行更新。从底层来看,MVI 的代价在于可能出现竞争条件,因为解决由竞争条件引起的一些错误会非常复杂。
在大型代码库中,维护大量的意图非常复杂。但我喜欢 MVI 的简洁性。在此,我已经假设您熟悉 MVI,因此我们将跳过示例,继续进行下一步。
MVC 或 MVP 架构
MVC(Model-View-Controller)
或 MVP(Model View Presenter)
架构在底层具有相同的行为。在 MVC 或 MVP 中,控制器或 Presenter 充当中介,通过对来自视图的事件进行响应来对模型进行修改。毫无疑问,MVC 或 MVP 通过使用某种交互器很好地将业务逻辑和表示逻辑分开。
但是它会使代码更加灵活以进行测试。但是,与此同时,它带来了接口的复杂性和视图与模型之间的紧密耦合。尤其是在大型代码库中,维护大量的接口会非常复杂。同上,我已经假设您熟悉这些内容,因此我们将跳过示例,继续进行下一步。
MVVM 架构
MVVM(Model-View-ViewModel)
架构将业务逻辑和表示逻辑分开,消除了各组件之间的紧密耦合。在 MVVM 中,ViewModel 充当模型和视图之间的桥梁。它对视图没有任何了解,也没有对视图的直接引用。
ViewModel 通过对来自视图的事件进行响应来修改模型。如果您是 Android 开发人员,您将对 MVVM 非常熟悉。MVVM 提供了任何应用程序所需的成功架构矩阵。它带来了灵活性、可扩展性和可维护性的好处。但是,同样,在大型代码库中,维护 ViewModel 内部的大量状态会非常困难。
哪种架构应该被采用?
众所周知,每种架构都有其优缺点。但最终,我们需要得出结论,选择应该遵循哪种架构。
为了解决这个冲突,您应该考虑以下关键点,这些点有助于根据您的需求选择架构。如果您问我我的意见,我建议考虑 MVVM 架构,因为它简单易懂。
- 架构是否足够灵活以适应未来的修改?
- 架构是否支持应用程序要求?
- 架构是否支持测试性和简洁性?
- 架构组件是否对读取开放,但对外部修改封闭?
- 团队采用架构是否容易?
- 它是否是干净而纯粹的架构,不依赖于第三方库?
总结
在 Kotlin Multiplatform Mobile 中,市场上有多种架构库,用于解决 KMM 中存在的多种问题。在 2023 年,Circuit 架构、BLoC 架构、Decompose 架构等都将推出,当前存在着大量的架构库。但我们是否应该使用这些架构?
一个架构不应该依赖于任何带来维护问题的架构库。
我宁愿考虑使用简单而干净的 MVVM 架构,它可以轻松扩展,并对未来的修改开放,而不依赖于任何其他的 API 或库。
相关文章:

Kotlin多平台最佳架构指南
在这篇文章中,我们将对 Kotlin 多平台移动端的最佳架构进行深入探讨。在2023年,作为 Android 开发者,我们会倾向于采用 MVVM 架构,因为它简单、灵活且易于测试。而作为 iOS 开发者,我们可能会选择 MVC、Viper 等架构。…...

【Vue3】父子组件传参
1. 父组件给子组件传值 父组件App.vue <template><div>父级</div><waterFallVue :title"name"></waterFallVue> </template><script setup lang"ts"> import waterFallVue from ./components/waterFall.vue …...

简单上手FineBI
简介 安装下载 下载的是V6.0.11版本 设置管理员账号 账号admin 密码123456 新建分析主题 添加数据 选择本地数据上传 选择示例数据上传 打开效果如下,点击“确定”,这样就将示例数据上传到分析主题中 分析数据——编辑数据 如果数据质量好…...

066、故障处理之热点问题
为什么要解决热点 分布式架构中各个组件的理想状态:资源利用率相对均衡 形成写热点的原因 高频访问的小表SQL执行计划不合理具有顺序增长属性的索引扫描 数据组织模型 例如数据是序列递增,则有可能数据全部都集中一个region上 ,或者集中…...

C/C++常用宏归纳
1 #define TO_STRING(t) #t #define MAP_TO_STRING(ot) {TO_STRING(ot), ot}TO_STRING宏接受一个参数t,并使用#运算符将其转换为字符串。这意味着当你在代码中使用TO_STRING(abc)时,它将被替换为字符串"abc"。 MAP_TO_STRING宏接受一个…...

在Windows 10/11 上安装GNS3模拟器
文章目录 在Windows 10/11 上安装GNS3模拟器简介支持的操作系统最低要求推荐配置要求最佳配置要求下载GNS3 all-in-one 安装文件安装GNS3在Windows 10/11 上安装GNS3模拟器 简介 本文档解释了如何在Windows环境中安装GNS3。你将学习如何: 下载所需的软件安装前提条件和可选软…...

React Route5 路由
💻 React Route5 路由🏠专栏:React 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向:目前主攻前端,其他知…...

海尔设计借助亚马逊云科技生成式AI,实现端到端的云上工业设计解决方案
海尔创新设计中心(以下简称海尔设计)成立于1994年,目前拥有400多名设计师,为海尔智家旗下七大品牌全球的所有产品提供设计创新和模式探索。亚马逊云科技为海尔设计提供了四个完整的云上解决方案,全面替代自有机房&…...

python数据结构和字符串用法
python数据结构和字符串用法 #Python 中数学运算常用的函数基本都在 math 模块 import math print(math.ceil(4.1)) #5 print(math.floor(4.9)) #4 print(math.fabs(-10)) #10.0 print(math.sqrt(9)) #3.0 print(math.exp(1)) #2.718281828459045 #Python随机数 #使用random(…...

ext4 - mballoc块分配机制
概述 ext4为了尽量避免block管理的碎片化有如此措施: 1.mballoc多块分配器。 buddy算法管理每个block group采用prellocation机制,氛围per-cpu local preallocation和per inode preallocation 小文件和大文件采用不同的策略小文件(具体怎么…...

Spring整合junit
1、导入pom坐标 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework</gro…...

Swift 让ScrollView滚动到具体某个位置
1. 使用scrollToItem方法滚动集合视图 DispatchQueue.main.asyncAfter(deadline: .now() 0.1) {let firstIndexPath IndexPath(item: 0, section: 0)let lastIndexPath IndexPath(item: self.recordArray.count - 1, section: 0)// Scroll to first itemself.collectionVie…...

【C语言day08】
int n5; int a[n][n2] 数组定义下角标不能为变量 注:C99标准中支持了使用变量本题考查的是二维数组的元素访问,A选项是 正确的,X[i]就是第i行的数组名,数组名表示首元素的地址,X[i]表示第i行的第一个元素的地址&#…...

【并发编程】ThreadLocal
从名字我们就可以看到 ThreadLocal 叫做线程变量,意思是 ThreadLocal 中填充的变量属于当前线程,该变量对其他线程而言是隔离的。 ThreadLocal 为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。 static ThreadL…...

如何提高自己的软件测试水平之bug定位
同学们在面试投简历的时候会经常看到人家公司JD上写的要求之一,如下: 这句话大家不要以为随便写写的,在我工作的十几年过程中起码见过10个以上试用期没过的公司新人,公司在衡量一个测试工程师是否专业的标准之一就是:…...

发点实用的快捷键(mac
切换输入法:ctrlspace /ctrloptionspace(更快捷 切换网页: shifttab 切换应用界面:alttab 关闭页面:altw 搜索:altspace 展示mac隐藏文件: Commangshift . (点) 以下是一些浏览器快捷键&am…...

Android播放多媒体文件——播放音频
以下内容摘自郭霖《第一行代码》第三版 播放音频 MediaPlayer类中常用的控制方法 方法名功能描述setDataSource()设置要播放的音频文件的位置prepare()在开始播放之前调用,以完成准备工作start()开始或继续播放音频pause()暂停播放音频reset()将MediaPlayer对象重…...

存储重启后,ceph挂载信息没了,手动定位osd序号并挂载到对应磁盘操作流程、ceph查看不到osd信息处理方法
文章目录 故障说明处理流程定位硬盘中的osd序号挂载osd到ceph上验证并拉起osd重复上面操作故障说明 我们的一个存储节点莫名其妙的重启了,不知道咋回事 但这样的问题就是,所有osd都down了 因为挂载信息没有写到fstab里面,所以不会自动up,并且没有挂载信息,并且也看不到o…...

Linux学习之循环处理位置参数
for处理位置参数 loopPositionFor.sh里边的内容如下: #!/bin/bash# show learningfor inputString in $* doif [ "${inputString}" "good" ];thenecho "learning"fi donechmod urx loopPositionFor.sh给当前用户把loopPositionFor…...

NLP实战8:图解 Transformer笔记
目录 1.Transformer宏观结构 2.Transformer结构细节 2.1输入 2.2编码部分 2.3解码部分 2.4多头注意力机制 2.5线性层和softmax 2.6 损失函数 3.参考代码 🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学啊* 所有&#…...

Pytorch个人学习记录总结 玩俄罗斯方块の深度学习小项目
目录 前言 模型成果演示 训练过程演示 代码实现 deep_network tetris test train 前言 当今,深度学习在各个领域展现出了惊人的应用潜力,而游戏开发领域也不例外。俄罗斯方块作为经典的益智游戏,一直以来深受玩家喜爱。在这个项目中&…...

PuTTY连接服务器报错Connection refused
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

11-3_Qt 5.9 C++开发指南_QSqlQuery的使用(QSqlQuery 是能执行任意 SQL 语句的类)
文章目录 1. QSqlQuery基本用法2. QSqlQueryModel和QSqlQuery联合使用2.1 可视化UI设计框架2.1.1主窗口的可视化UI设计框架2.1.2 对话框的可视化UI设计框架 2.2 数据表显示2.3 编辑记录对话框2.4 编辑记录2.5 插入记录2.6 删除记录2.7 记录遍历2.8 程序框架及源码2.8.1 程序整体…...

神码ai火车头伪原创插件怎么用【php源码】
大家好,本文将围绕python绘制烟花特定爆炸效果展开说明,如何用python画一朵花是一个很多人都想弄明白的事情,想搞清楚用python画烟花的代码需要先了解以下几个事情。 1、表白烟花代码 天天敲代码的朋友,有没有想过代码也可以变得…...

13.Netty源码之Netty中的类与API
highlight: arduino-light ServerBootstrap Bootstrap 意思是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty 程序,串联各个组件,Netty 中ServerBootstrap 是服务端启动引导类。 java //泛型 AbstractB…...

C# 如何检查数组列表中是否存在数组
原文:https://www.coder.work/article/2958674 列表: 一个数组列表,想检查一个确切的数组是否在列表中 List<int[]> Output new List<int[]>(); 有一个数组 int[] coordinates 想检查coordinates 数组是否在Output 列表中&…...

AI课堂教学质量评估系统算法 yolov7
AI课堂教学质量评估系统通过yolov7网络模型框架利用摄像头和人脸识别技术,AI课堂教学质量评估系统实时监测学生的上课表情和课堂行为。同时,还结合语音识别技术和听课专注度分析算法,对学生的听课专注度进行评估,生成教学质量报告…...

eventBus使用遇到的坑
**问题:**通过eventBus传递的参数,在子组件的methods中无法通过this.使用。 **思路:**考虑组件方法的执行顺序(vue生命周期执行顺序) **解决办法:**在传递参数的组件外 this.$nextTick this.$nextTick(() …...

ChatGPT应用|科大讯飞星火杯认知大模型场景创新赛开始报名了!
ChatGPT发布带来的 AI 浪潮在全球疯狂蔓延,国内掀起的大模型混战已经持续半年之久,国产大模型数量正以惊人的速度增长,据不完全统计,截止7月14号已经达到了111个,所谓的“神仙打架”不过如此了吧。 ( 包括但…...

DM8 DSC备份还原
1、检查磁盘空间 检查服务器磁盘空间使用情况,确认磁盘有充足的空间存放物理备份。 查看磁盘空间使用情况(备份在端点0,此处检查端点0) su - dmdba [dmdbacentos-04 ~]$ df -h 文件系统 容量 已用 可用 已用% …...