KunMinX

KunMinX

V2EX 第 352257 号会员,加入于 2018-09-26 14:47:11 +08:00
根据 KunMinX 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
KunMinX 最近回复了
2023-01-09 16:19:57 +08:00
回复了 Aicerk 创建的主题 MacBook Pro 新款 MacBook Pro 屏幕更容易被损伤
镀膜屏幕和镀膜眼镜片一样脆弱,不宜在 40 度以上环境使用,不宜用酒精擦拭,不宜接触碱性溶液,不宜粘附橡胶之类的材质,以免脱膜。
2022-12-11 23:52:49 +08:00
回复了 luvsic 创建的主题 程序员 mac 和 windows 双持的各位,你们会改键位吗
我通常是 mac 通过 Microsoft remote desktop 访问 windows ,这样可以直接延续 mac 的键位和鼠标滚动方向
2022-11-08 14:18:52 +08:00
回复了 lslvxy 创建的主题 程序员 想换电脑了, MAC or ThinkPad
m1 芯片 mac 可以玩原神。windows 建议台式机。
2022-11-05 13:47:44 +08:00
回复了 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   ·   实用小工具   ·   2580 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms · UTC 11:31 · PVG 19:31 · LAX 04:31 · JFK 07:31
Developed with CodeLauncher
♥ Do have faith in what you're doing.