旦用难回 Jetpack MVI 最佳实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
KunMinX
V2EX    Android

旦用难回 Jetpack MVI 最佳实践

  •  
  •   KunMinX 2022-07-05 10:50:02 +08:00 13428 次点击
    这是一个创建于 1199 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如您是 UnPeek-LiveData 资深玩家,今天这框架请不要错过

    刚于 Github 发行《 MVI 最佳实践》& 唯一可信源成熟态 “MVI-Dispatcher”,通过它可一举消除 “mutable 样板代码 + LiveData 连发事件覆盖 + LiveData.setValue 误用滥用” 等高频痛点问题,

    欢迎 star 、test 、feedback 三连~

    https://github.com/KunMinX/Jetpack-MVI-Best-Practice

    第 1 条附言    2022-07-30 13:26:05 +08:00
    1.互联网非说理地,评论区是我地盘,我是这的地头蛇。你在我地盘发表作品,就得照顾我大师光环,否则别怪我随便找个理由嘲讽打压抬杠抹黑引战孤立,以针对你个人进行人身攻击寻求优越感。

    2.Base64 是一好东西,然实践过程中易得,标准 Base64 在 URL 场景下存在不可预期问题,故业界萌生 Base64 改良版 Base64.UrlEncoder 作为最佳实践。

    同理,响应式编程、MVI 属理想化模型,在实践过程中易得,标准 MVI 在 Java 命令式编程 Android View 页面开发场景下存在不可预期问题,故萌生 MVI 改良版为最佳实践。



    3.你说这么多没用,我就是要随便找个理由打压你 你这改良版,和理想化实验环境理论模型有出入,你这设计违背理想化理论,故你就是水平臭,你就是对 MVI 理解有偏差,你活该被指责攻击。

    4.你不该对 “最佳实践” 感兴趣,更不该公开分享,你公开分享,就是在挑衅别人大师光环,你都 “最佳” 了,别人怎么办?

    5.别指望别人去查百科了解 “最佳实践” 含义 最佳实践( best practice )是一管理学概念,“认为存在某种技术、方法、过程、活动或机制可使生产或管理实践结果达到最优,并减少出错可能性”。



    6.如不想因为 “最佳实践” 被杠,你最好别取《 MVI 最佳实践》这样标题,最好是《在 MVI 基础上,根据广泛实践,形成某种改良版,以使生产或管理实践结果达到最优,并减少不可预期错误》。

    7.不过,就算你标题有 45 字这么长也不行,欲加你罪,何患无辞。就是妒忌你,总有理由三人成虎泼你脏水。你越认真,越有理由黑你。

    8.你以后不要再分享了,你觉得不错东西,自用就行了。不必做个傻逼程序员,动不动觉得自用可惜,迫不及待分享。这里有 100 个理由恶意揣测你动机,你连呼吸都是错。
    15 条回复    2022-09-03 17:45:05 +08:00
    fromzero
        1
    fromzero  
       2022-07-05 11:00:49 +08:00   10
    又来发明新名词了,前端用烂的单向数据流。不说了,赶紧出付费教程,我第一个当韭菜
    fromzero
        2
    fromzero  
       2022-07-05 11:03:09 +08:00   3
    想学习 mvi 的同学大可直接去看 aribnb 的 https://github.com/airbnb/mavericks ,基于 jetpack flow ,里面的代码质量细细研读会有很多收获
    KunMinX
        3
    KunMinX  
    OP
       2022-07-05 11:18:06 +08:00
    根据你的阴阳怪气,很难让人不无语。就踩吧,黑吧,毁灭吧 ~
    xwdz9989
        4
    xwdz9989  
       2022-07-05 14:51:35 +08:00
    营销鬼才
    ClaudeCode
        5
    ClaudeCode  
       2022-07-06 10:46:50 +08:00   4
    每次来 Android 节点发推广没人鸟你,心里没点数?
    矫揉造作,直接去当 stormzhang 门徒得了,也好早日财务自由~
    cenbiq
        6
    cenbiq  
       2022-07-06 11:01:04 +08:00 via iPhone
    @fromzero 一直想找一个这样的库,感谢老铁
    XXWHCA
        7
    XXWHCA  
       2022-07-07 09:40:22 +08:00
    @fromzero 明白这就看一楼推荐的库了解一下
    KunMinX
        8
    KunMinX  
    OP
       2022-07-07 11:03:00 +08:00
    演的还挺像。1 、2 、3 、4 、5 ,人差不多也齐了,来个大家整个 “三人成虎”。
    fromzero
        9
    fromzero  
       2022-07-09 23:24:49 +08:00
    @KunMinX 今天闲来无事,先来分析你的代码吧。 首先,mvi 的关键核心是状态机,不可变的状态,以及单向的数据流向,这也是现代声明式 ui 的思想,故 mvi 和 compose flutter 以及 swift ui 是十分契合的。大神的最佳实践中的 Event 应该就是 state 了,页面通过 out 订阅 state 的变化更新 ui ,这个没问题,但是不可变呢?你为什么直接更改 event 里的值啊?你这里也没有 reducer 的体现啊?![image.png]( https://s2.loli.net/2022/07/09/yWzxPYiQrdgXkK3.png) 另外 side effect 的情况本最佳实践怎么处理呢?
    fromzero
        10
    fromzero  
       2022-07-10 20:02:01 +08:00
    @fromzero 不可变这里我看错了一丢丢,爱坤大神这里的 event 应该是代表每个 intent 产生的事件,但是数据什么的都包在 event 里面,然后再把 event 的数据赋值给 state 刷新,这里 state 的赋值也违法了不可变,那这里也很奇怪,我干嘛不直接拿 event 的数据刷新呢,out 监听的为什么是 event 不是 state ,那不是变成了 事件驱动 ui 而不是状态驱动 ui ? ![image.png]( https://s2.loli.net/2022/07/10/S4bTNOGp5FmDi1v.png)
    fromzero
        11
    fromzero  
       2022-07-10 20:43:08 +08:00   2
    总结(仅仅是本菜鸡的个人观点):
    整体架构看起来没啥问题,用户触发事件,请求数据,ui 监听事件改状态刷新 ui ,完美的单向数据流。but
    * 违反不可变,比如我在监听处偷偷修改 event 里面的值,直接破坏其他监听者的逻辑
    * 没有状态机,只有一个 Event 事件队列机来发事件,通过监听 event 的数据,然后扔给给状态,而且状态这个变量 mStates 是由 ui 自己维护的(我自己维护我自己的状态?不应该是监听状态吗?)
    fromzero
        12
    fromzero  
       2022-07-10 21:02:11 +08:00
    @KunMinX 说实话分析完我是吓一跳的,我原本还是挺认可你的技术的,虽说喜欢造新名词,但是之前的技术文章多少有几篇还不错的,我今天去看了一下你的重学 android 已经涨到¥ 379 了,静下心多打磨点干货吧。
    GetCore
        13
    GetCore  
       2022-08-14 01:01:07 +08:00
    KunMinX
        14
    KunMinX  
    OP
       2022-08-30 16:01:31 +08:00
    统一回复:

    MVI 是实现单向数据流的一种方式,本质上是一种 IO 闭环,也即只要遵循函数式编程特性:唯一入口 + 唯一出口 + 无副作用,就可视作是 MVI 。

    reduce 仅仅只是权宜之计,或者说主流解决方案,目的是在当下计算设备性能有限情况下,对状态集做的统一优化。实现 MVI 方式千千万,我个人认为 reduce 不能算是 MVI 本质。

    至于 sample 案例中为什么没有为 “Intent” 字段添加 final ,那是因为 Java 下想要实现 Koltin val 同等效果,样板代码瞬间会飙出许多。val 是为了消除 数据一致性问题,而 java final 滋生的样板代码反而在日后容易滋生更多 “一致性问题”,

    这几天腾出手开始解决这个问题,刚刚提交了可用于 Java 8 的 sealed class ,专门优化这问题。

    最后,任何技术都存在演变的过程,没有什么一出生就是完美无缺,我希望一切都能实事求是交流,而不是高高在上的姿态嘲讽打击。

    和所有我开源过的项目一样,MVI-Dispatcher 也是一个长期项目,我们希望打磨一个极低学习成本,在多数场景下都能稳定运作的框架。
    KunMinX
        15
    KunMinX  
    OP
       2022-09-03 17:45:05 +08:00
    也不能说是优化,应该说是一种细化和规范,提醒人们 newState 务必基于 oldState copy 而来,如果不是特别必要,比如如果业务细化程度不足以裂变出 partialChange ,那么在 MVP (最小可交付产品)设计中可以没有 reducer 。

    目前觉得有必要引入 reducer 的场景在于事故高发地段,需要捕捉 state 变化的路径,乃至手动配置个 reducer 来管理 states 列表。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     936 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 19:32 PVG 03:32 LAX 12:32 JFK 15:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86