KunMinX

KunMinX

V2EX 第 352257 号会员,加入于 2018-09-26 14:47:11 +08:00
根据 KunMinX 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
KunMinX 最近回复了
255 天前
回复了 Aicerk 创建的主题 MacBook Pro 新款 MacBook Pro 屏幕更容易被损伤
镀膜屏幕和镀膜眼镜片一样脆弱,不宜在 40 度以上环境使用,不宜用酒精擦拭,不宜接触碱性溶液,不宜粘附橡胶之类的材质,以免脱膜。
284 天前
回复了 luvsic 创建的主题 程序员 mac 和 windows 双持的各位,你们会改键位吗
我通常是 mac 通过 Microsoft remote desktop 访问 windows ,这样可以直接延续 mac 的键位和鼠标滚动方向
317 天前
回复了 lslvxy 创建的主题 程序员 想换电脑了, MAC or ThinkPad
m1 芯片 mac 可以玩原神。windows 建议台式机。
320 天前
回复了 sqyaoyuan 创建的主题 MacBook Pro 看来 MacBook pro 14 还是不要一直插着电用
可以在设置中查看是否具备 “电池优化” 选项,如有,开启即可。
充到 80%,自动会走电源线路,不再走电池。24 小时插电也无事。
2022-09-10 19:30:45 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
@Guaidaodl
也是,考虑线程安全。
2022-09-10 12:54:47 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
@Guaidaodl

受你的启发,想到一个简便方式了。类似于把 copy 环节后置,也即开发者写代码时,像往常一样直接改字段,然后回推时给到 UI 的是重新 copy 的 uiStates ,也即可以给观察者套上一层 wrapper 来内部实现 copy 。
2022-09-10 00:44:02 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
@reactna1ve 理解你意思了,2 包含异步顺序等问题。
2022-09-09 12:00:59 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
2022-09-09 12:00:48 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
没错,3 十分有体会,包括 editText 等自身能产生数据的控件情况。
5 的话,uiEvent 由于会改变 mvi-view 以外的环境(比如新增一个 window ,新增一个页面到返回栈),所以对纯函数而言又是副作用,需要某种方式解决,
2 没有理解,我的理解是,uiStates 和 actions 都聚合在 mvi-model 中,从发起 intent 到 action 为止,这期间可以记录本次操作路径,并且本次发起请求和回推结果,都可以记录
2022-09-08 17:03:48 +08:00
回复了 KunMinX 创建的主题 Android 简单分享下我对 MVI 的理解
这几天讨论 MVI 的人有点多,我简单分享下自己的理解。

MVI 是响应式编程的产物。

响应式编程有个潜规则:一个控件只能在同一个粘性观察者( BehaviorSubject )中响应,

然而随着业务发展,开发者很容易误在多个粘性观察者中放置同一控件实例,即引发 “多个粘性观察者不符预期回推” 的隐患,

MVI 主要就是来解决这问题。通过将页面 uiStates 聚合在一处,控件只从这唯一观察者响应数据变化,从而确保环境重建时,回推的最后一次数据来源唯一,乃至符合预期。

由于控件集中响应,uiStates 字段不可变,加上每次根据 intent 执行业务,拿到的都是当前 action 当前 partialChange ,故唯有通过 copy 整合当前 partialChange 到上一次 uiStates ,来确保 uiStates 的延续,这个 copy 以延续的过程就叫 reduce ,

不过如果不是有专门的需求,我们无须特意写个 reducer 类来体现,而仅仅是 reduce 方法或直接 copy ,心意到了即可,

与此同时,UI 侧都是通过 diff 来判断本次某控件是否刷新。jetpack compose 无须开发者手动 diff ,其内部类似前端 DOM ,根据本次注入的声明树自行在内部差分合并渲染新的内容。当前我个人是用 DataBinding observableField 来做 diff 。

当然 MVI 也有其不便之处,由于它本来就是要通过聚合 uiStates 来规避上述不符预期问题,故 uiStates 很容易爆炸,特别是 UiStates 居多情况下,每次回推都要做数十个 diff ,在高实时变化的场景下,有一定的性能影响,

MVI 许多页面和业务都需手写定制,难通过自动生成代码等方式半自动开发,故我们我们不如退一步,反思下为什么要用响应式编程?

穷尽所有可能,我觉得最合理的解释是,响应式编程十分便于单元测试 —— 由于控件只在观察者中响应,那么有输入就必定有回响,

也是因为这原因,官方出于完备性考虑,以响应式编程作为架构示例。

现实中情况往往十分复杂。

android 当初为了站稳脚跟,选择复用已有的 java 生态和开发者,乃至使用 java 来作为官方语言,后来 java 越来越难支持现代化移动开发,故而转向 kotlin ,

用 kotlin 的开发者,更容易跟着官方文档走,一开始就是接受 flow 、reactive 的那一套,且 kotlin 的确抹平了语法复杂度,所以天然就是响应式编程的模式在开发,如此便有机会踩坑,并且有动力通过 MVI 的方式来改善响应式编程开发。

然而 10 个 android 7 个纯 java ,其中 6 个从不用 rxJava ,剩下一个还是偶尔用用 rxjava 的线程调度切换,

所以响应式编程在 java android 开发中的推行不太理想,领导甚至可能为了照顾多数同事,而要求撤回响应式编程代码,如此便很难有机会踩坑,更谈不上使用 MVI ,

也因此,实际开发中更多考虑的是,如何从根源上避免各种不可预期问题。对此从软件工程角度出发,我在设计模式原则中找到答案 —— 任何框架,只要遵循单一职责原则,就能有效避免各种不可预期问题,反之过度设计则易引发不可预期问题,

例如 BehaviorSubject ,实际上是一种过度设计,因为它的观察者是开放式,一旦开了这口子,后续便不可控,一个良好的设计是,不暴露不该暴露的口子,不给用户犯错的机会。一个正面的案例是 DataBinding observableField ,一个控件只能在 xml 中绑定一个,从根源上杜绝上述不符预期问题。

不过 DataBinding 也存在过度设计,例如开发者能拿到 binding 实例去直接调用控件实例,如此 observableField 数据绑定的努力前功尽弃。

目前想到的就是这些,有不同观点欢迎补充。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3635 人在线   最高记录 5930   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 05:09 · PVG 13:09 · LAX 22:09 · JFK 01:09
Developed with CodeLauncher
♥ Do have faith in what you're doing.