tag mvu, fsharp, avalonia, elm, fp
本来用 rxui 好好的,为什么非跑去用什么mvu。
rxui很强大,v-vm绑定,值的联动,简单高效的validation验证,复杂强大的dynamicdata。
已经用习惯了只要不是为了简单快速套个gui,都可以直接上手用rxui开发。不过也存在问题,界面离不开xaml,一些场景下必须要依赖ItemControl,Selector来构建高效的界面,不可能按照dynamicdata的思路,数据变换就全部重建渲染。
用mvu主要是为了上手fsharp,并且期待这种不可变的架构能够减少对gui的维护成本。代码要过几年还要快速看懂,要不就能短则短,要不就依照某一范式。
view -> model(state) -> update(msg)
view的形状纯依靠当前state里的数值来呈现,假设把update移除,视图也能很好的被渲染。
而state的数值变化只有一个途径,就是通过update函数的返回值,并且每次都是全新的state,将旧的整个状态完全替换。
这个路径完全是单向依赖。简洁明了,不会因为不知道哪儿导致状态改变了而四处寻找。
因为所有变化大量消息都聚集在update,所以update最好保持简洁,只做关键的状态更新和传递出副作用的动作。
问题在于update的变化源,还有很多没搞明白的地方,上手过程中很苦恼从哪儿拿到当前的state状态,以及从哪儿能拿到dispatch,即update更新model的手枪。
1. 来自界面的输入,只要是任何发源于界面的事件,比如 click,各类event,在界面上从界面发出就可以直接拿到发送消息的dispatch,由此来改变状态出发一些操作
2. 来自update本身,update的目的是为了改变状态,而对于一个gui程序,读一个文件是副作用,启动一个程序是副作用,配置保存写入文件也是副作用,似乎只要是和界面state以外的东西有关那都是副作用。对于这个Impure的世界,不可避免有副作用的产生和界面外的操作,除非这个界面(窗口)只依赖于创建他时递给他的参数,并且不对外界产生任何影响。
update里,可能一些消息被触发后,做一些事儿,然后原封不动的返回一模一样的状态。所谓做一些事儿便是副作用,这个副作用产生的影响可以是立即的,也可以是延迟的,这被叫做命令Command。在elmish里,立即产生的消息由 Cmd.ofMsg 发送,这类似于continueWith,一个消息处理完接着处理另一个消息,这里也可以用到Cmd.batch 用于组合多个命令。延迟的副作用由 Cmd.ofEffect处理,改名前叫ofSub,换句话话说其实就是处理事件回调或异步,任何不在主线程发出的事儿,比如网络资源请求,磁盘io,在函数式里这就限制得更严格了,理论任何副作用都应该属于这里。
继由这俩命令,我可以拿到dispacher,来操作界面->更新界面的状态。
3. Subscription,订阅来自mvu的最顶层 Program,文档说明 Subscription是外界的输入源对系统(窗口)内的修改。个人感觉作用有限。Subscription就是订阅和释放的结构,每次视图内的状态更新时也都会去尝试更新一下订阅的状态,如果不需要了,你可以将订阅dispose掉(通过返回新的订阅列表,或者空的列表这样就全部移除了),所以这样的事件源比较好想象,比较适合timer,自设全局事件,比如监听磁盘改变的事件,这些对你的界面交互呈现有所影响,所以你使用。
Command是唯一产生副作用,包裹副作用的地方,所有副作用都可以写在command里。Subscribe也许也可以产生副作用,也可以纯。
elm和fs很像总觉得是谁抄的谁,还是说所有函数式语言都这样,不过elm这种封闭语言肯定是似了。关于fp还有太多不懂的概念以及实际的思考方式,不急着写项目,慢慢补充知识吧。
函数式编程简介(上)——通过 elm 入门 FP - 知乎 (zhihu.com)
Videos | F# for fun and profit (fsharpforfunandprofit.com)
前端 - 笨办法学函数式编程:Elm 初体验 - 寒蝉效应 - SegmentFault 思否
Elmish.WPF/TUTORIAL.md at master · elmish/Elmish.WPF · GitHub
标签:状态,初体验,界面,elm,update,state,副作用,Elmish From: https://www.cnblogs.com/kimika/p/17455164.html