满眼只有React和Vue,却对前端数据层几乎一无所知

广告位招租
扫码页面底部二维码联系

Angular是最早声称基于MVVM架构【版权所有,侵权必究】【原创内容,转载请注明出处】的前端框架,但在我眼里,Angular根【未经授权禁止转载】【本文受版权保护】本没有M这一层,React和Vue也好不本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】到哪里,目前最热的三大框架,都只是V层前【本文首发于唐霜的博客】【转载请注明来源】端框架,和M层谈不上什么联系。

原创内容,盗版必究。【原创内容,转载请注明出处】【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。

不过,在此前我自己写过的一篇爽文《原创内容,盗版必究。前端状态管理设计——优雅与妥协的艺术【本文首发于唐霜的博客】》里,我自己还曾经提到,Vue的组件管理转载请注明出处:www.tangshuang.net原创内容,盗版必究。有模型管理的影子,如今回忆起来,实属草率【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net。不过还好,我并没有在文章中给前端状态管【原创内容,转载请注明出处】原创内容,盗版必究。理和模型管理之间的关系下一个定论,避免打原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】脸。但是在我的播客节目《Robust:程著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】序员的Talk Place》的第15期《跳出框架看前端分层结构原创内容,盗版必究。》中,我却明确提出了前端分层结构,妥妥的【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】在一些问题上给自己挖了坑。

【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】

不是我冒犯,包括我自己在内,如果满眼都是著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】React和Vue之类的前端框架、库,那【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】么可以说,对前端数据层几乎一无所知,就算著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】把前端框架玩的贼溜,对前端架构的理解,也【原创不易,请尊重版权】【作者:唐霜】不过是井底蛙之王。

【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net

前端热门框架只是视图框架【本文首发于唐霜的博客】

【原创内容,转载请注明出处】【未经授权禁止转载】【原创内容,转载请注明出处】【本文首发于唐霜的博客】

本文将主要讨论的是业务型前端应用中的数据【本文受版权保护】本文作者:唐霜,转载请注明出处。层。业务型前端应用,主要处理的是基于某个业务【本文首发于唐霜的博客】【本文受版权保护】流程而实现的产品形态,它和游戏、大数据展原创内容,盗版必究。原创内容,盗版必究。示、同声传译、音视频处理等前端应用非常不本文版权归作者所有,未经授权不得转载。【本文受版权保护】同,它关注业务流程在用户眼中的呈现,常常【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。以业务流程的准确实现为目标,例如饿了么点【转载请注明来源】【关注微信公众号:wwwtangshuangnet】餐、腾讯云服务管理平台、淘宝电商平台等,著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】这些都是典型的业务系统,也是当下整个互联【未经授权禁止转载】本文作者:唐霜,转载请注明出处。网行业最主流的产品形态。因此,React未经授权,禁止复制转载。【未经授权禁止转载】、Vue和Angular火,决定因素还是【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。时代背景,即业务型应用的大势所趋。

【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。

从技术层面讲,三大框架(甚至包括Flut未经授权,禁止复制转载。【版权所有,侵权必究】ter)虽部分理念不同,但从底层视图绘制【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。去思考,它们都是基于结构性视图绘制的实现【作者:唐霜】【关注微信公众号:wwwtangshuangnet】逻辑。无论是基于DOM树形结构的框架,还著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】是React Native,它们都有一个转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。共同实现特征,就是需要“布局”,而且是“未经授权,禁止复制转载。【未经授权禁止转载】结构性布局”(比如基于类XML语言的布局【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】)。本质上它们是Retained Mode GUI,而转载请注明出处:www.tangshuang.net【本文受版权保护】非Immediate Mode GUI。结构性布局框架,在Canvas、VR 【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】3D环境中就会遇到麻烦,因为在这类视觉环【本文受版权保护】【版权所有】唐霜 www.tangshuang.net境下遵循“坐标定位布局”,三大框架在这种著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。场景中基本就没有发挥余地。在DOM环境下【原创内容,转载请注明出处】【未经授权禁止转载】,处理动画、复杂交互(例如拖拽排序这个简著作权归作者所有,禁止商业用途转载。【作者:唐霜】单的功能),三大框架也不如jQuery顺本文版权归作者所有,未经授权不得转载。【转载请注明来源】利,因此,如今的前端框架,仅仅是在业务系【转载请注明来源】【本文首发于唐霜的博客】统领域中,具备竞争力,脱离业务系统,它们【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】的发挥空间和所带来的收益,就会瞬间下降,【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net如果脱离“结构性布局”,它们的收益几乎为本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】负数(React也在尝试实现canvas转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。和vr渲染,其实很令人期待)。

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【原创不易,请尊重版权】未经授权,禁止复制转载。

虽然火力都在业务系统领域,但是对于对业务本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。数据逻辑有极强要求的应用,却在前端层面,【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。至今为止,没有统一的认识。前端数据层的缺转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net少,是很多业务系统越来越难以维护的重要原【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。因。

未经授权,禁止复制转载。【未经授权禁止转载】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。

React是纯视图库,Vue和Angul未经授权,禁止复制转载。【本文首发于唐霜的博客】ar并不比React内涵或外延多多少,三【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】者本质上没有区别,甚至react在视图抽原创内容,盗版必究。【本文首发于唐霜的博客】象上可以复用到其他平台,做canvas或原创内容,盗版必究。【原创内容,转载请注明出处】vr的尝试,而angular几乎无法做这未经授权,禁止复制转载。【转载请注明来源】些尝试。在架构层面,它们声称遵循MVVM【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。架构,特别是Angular认为自己拥有完【未经授权禁止转载】本文作者:唐霜,转载请注明出处。整的框架结构。

【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】【原创内容,转载请注明出处】

MVVM架构示意图,转载请注明出处:www.tangshuang.net来自网络未经授权,禁止复制转载。

原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。

在上图示意中,VM通过ajax和Mode转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】l交互,这显然是一种奇葩解释。事实上,号【本文受版权保护】【版权所有】唐霜 www.tangshuang.net称拥有完整架构的Angular确实是没有【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】自己的Model层,它只有VM层的实现,【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。并且规定了V层和VM层如何编程,但在M层【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net毫无建树,而且所谓的VM层也是为V层服务【转载请注明来源】著作权归作者所有,禁止商业用途转载。。这也印证了主流框架本质上是V层框架的观【版权所有】唐霜 www.tangshuang.net【本文受版权保护】点。

著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】转载请注明出处:www.tangshuang.net

为了强行往完整的MVVM或MVC靠,很多原创内容,盗版必究。未经授权,禁止复制转载。人将基于Redux或其他类似全局状态管理著作权归作者所有,禁止商业用途转载。【作者:唐霜】器的应用结构称为真正符合完整MVC的架构【未经授权禁止转载】未经授权,禁止复制转载。。但这个说法实际上有点胡扯,全局状态管理转载请注明出处:www.tangshuang.net【转载请注明来源】是V层框架的衍生品,是属于解决问题过程中【原创不易,请尊重版权】【作者:唐霜】衍生出来的新问题,React和Vue都是著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】基于状态驱动的V层视图框架,全局状态管理【本文受版权保护】【版权所有】唐霜 www.tangshuang.net器本质是在解决这类(基于virtual 【本文受版权保护】【原创内容,转载请注明出处】dom的)视图框架的状态管理优化问题,根原创内容,盗版必究。【原创不易,请尊重版权】本和MVC中的M没有什么关系,也就更别说【转载请注明来源】转载请注明出处:www.tangshuang.net和模型设计有什么关联,自然也享受不到模型【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。设计的好处。

【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net【版权所有,侵权必究】【本文首发于唐霜的博客】

而且冒昧的说,基于React这种组件结构【本文首发于唐霜的博客】【原创不易,请尊重版权】性布局的视图层框架,如果无法解决全局状态【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。管理器的隔离性,那都是在浪费时间和资源。本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net什么是这里的“隔离”呢?简单说就是一个页本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】面可能有两个React应用(本质是一个大【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】组件),而每个应用有一个自己的全局状态。【转载请注明来源】【本文受版权保护】(不过比较幸运,Redux可以做到这一点【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。。)为什么这么说?我们可以回顾一下,在没【本文受版权保护】【本文受版权保护】有数据(这里单纯理解为后端数据)参与的R【作者:唐霜】【本文首发于唐霜的博客】eact应用中,编程是非常简单顺利的,因【本文受版权保护】【原创不易,请尊重版权】为React视图完全是靠状态驱动的。然而原创内容,盗版必究。【原创内容,转载请注明出处】,当引入一个数据源之后,整个编程复杂度将【转载请注明来源】本文作者:唐霜,转载请注明出处。会瞬间提升几倍,而且,越是使用Redux【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】这类全局状态管理器,复杂度越高,甚至比不原创内容,盗版必究。【转载请注明来源】上单纯在组件中直接ajax请求数据来的简【本文首发于唐霜的博客】【转载请注明来源】单。这是为什么?很多人根本没有思考过这个【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net问题。

原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net

我曾经有一种想法是,既然React是单纯【转载请注明来源】【本文受版权保护】的UI库,那么我能否自己建立一套MVC的【转载请注明来源】【本文首发于唐霜的博客】框架,其中V层由React来承担,M层我【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。自己实现一套逻辑?这种想法是好的,而且实未经授权,禁止复制转载。原创内容,盗版必究。践起来也有可能实现。然而在真正实现过程中转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net,我发现整个编程已经被React的编程范【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。式框定住了,虽然React声称是纯UI库【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。,但是它实际上规定了开发者写组件的方法,【转载请注明来源】【本文受版权保护】因为对于组件而言,状态是完全要自治的,一【关注微信公众号:wwwtangshuangnet】【本文受版权保护】棵组件树最终表现成什么样子,它只能被内部本文作者:唐霜,转载请注明出处。【本文受版权保护】的状态或外部的props控制,要真正实现本文版权归作者所有,未经授权不得转载。【本文受版权保护】MVC,就必须由全局状态管理器作为中间人原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。,和M层打交道才能实现(如下图),这导致【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。整个编程会非常复杂,一旦按照这种逻辑去实转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。现,那带来的成本,比当前热门的只需要一个原创内容,盗版必究。本文作者:唐霜,转载请注明出处。全局状态管理器的编程方式更复杂,完全没有【本文首发于唐霜的博客】【本文受版权保护】必要。(不过,由于hooks的出现,这种原创内容,盗版必究。转载请注明出处:www.tangshuang.net局面可能会被打破。)

【作者:唐霜】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net

在原有的React编程范式上叠加Mode【版权所有】唐霜 www.tangshuang.net【转载请注明来源】l层编程示意图

【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】

所以,无论是三大框架本身,还是全局状态管【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。理器,都是V层编程,都没有真正解决前端数未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。据层问题。而基于这套编程范式的框架,要再【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net去实现M层,又会增加更加复杂的问题。除了本文版权归作者所有,未经授权不得转载。【作者:唐霜】三大框架之外的一些非V层前端框架,却在业【原创不易,请尊重版权】【未经授权禁止转载】务系统领域的理念上,可能更优秀。以Cyc【转载请注明来源】转载请注明出处:www.tangshuang.netle.js框架为例,它本身虽然也是落足到【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】UI上,但是它在数据到状态到UI的过程中未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。,增加了“流”的逻辑,也就是说,它是两端本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】可扩展的,基于这个扩展,数据管理的能力实本文版权归作者所有,未经授权不得转载。【本文受版权保护】现起来也更容易一些。而已经快被大家遗忘的本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netBackbone框架,干脆在UI层没有强【作者:唐霜】【本文首发于唐霜的博客】制,虽然也是基于jQuery的,但是它不【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】限制开发者的视图层实现逻辑,它更关心Mo未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】del如何触发View的重绘。从这些角度【作者:唐霜】原创内容,盗版必究。看,这些非主流的边缘框架,反而在前端框架本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】架构层面走的更远,起码它们不是单纯V层框【转载请注明来源】未经授权,禁止复制转载。架。

本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】未经授权,禁止复制转载。

前端分层结构转载请注明出处:www.tangshuang.net

【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。【转载请注明来源】【作者:唐霜】

业务型应用和纯工具应用不同,前端业务系统本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】不是无源之水,不可能凭空产生数据,如果脱转载请注明出处:www.tangshuang.net原创内容,盗版必究。离业务数据,它将变得毫无用处,一文不值。未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。在浏览器里面运行起来之后,前端程序会申请【本文受版权保护】未经授权,禁止复制转载。内存,产生一些运行时数据,这些数据本质上转载请注明出处:www.tangshuang.net【版权所有,侵权必究】是驱动V层渲染的状态,而非来自M层的数据本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】。前端数据的来源有很多,最主要的包括:从原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。后台api请求得到的,通过websock【转载请注明来源】【版权所有】唐霜 www.tangshuang.netet等方式接收到的,通过postMess本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。age等方式接收到的,从localSto本文作者:唐霜,转载请注明出处。【未经授权禁止转载】rage等前端持久化存储读取的,读取文件【转载请注明来源】【本文受版权保护】内容解析后得到的……这些数据来源组成了前本文作者:唐霜,转载请注明出处。【本文受版权保护】端应用数据层的基础、源头。前端数据层,即原创内容,盗版必究。【未经授权禁止转载】围绕这些数据源,和数据源上游打交道,并且著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】连接它的下游——视图层——的特定处理逻辑本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。

本文版权归作者所有,未经授权不得转载。【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】

原创内容,盗版必究。【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】

其中,和我们业务相关的,最核心的数据来自【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。于API接口吐出的数据。不过理论上,这一【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。层数据属于VO(View Object)未经授权,禁止复制转载。【本文首发于唐霜的博客】,它并不最贴近业务本身,而是后端为了提供【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net符合前端需要的数据,经过层层处理,最终输【原创内容,转载请注明出处】【转载请注明来源】出的数据。

【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】

图片【访问 www.tangshuang.net 获取更多精彩内容】来自网络本文作者:唐霜,转载请注明出处。

【本文受版权保护】【未经授权禁止转载】原创内容,盗版必究。本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】

也就是说,对于单纯从界面出发的前端应用而【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。言,其实并不需要涉及业务本身。可是非常不【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】巧,业务流程越复杂的应用,在前端对业务的依赖【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。更强。举个例子,一个流程管理系统,不同角色对某转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。一个操作的效果不同,而且不同角色操作之后【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net,会进入到各自的子流程中。由于这种逻辑是本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。前置的,用户在操作之后,需要立即在界面上著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】得到反馈,而不能等到拉取后端数据来渲染。【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net直白的讲,这类业务逻辑只能写在前端,才能【作者:唐霜】【原创内容,转载请注明出处】满足业务交互的需求。所以,在另外的一些系未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net统中原本应该由后端完成的数据业务处理,此【关注微信公众号:wwwtangshuangnet】【作者:唐霜】时,可能需要在前端完成。于是上图中的数据【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】流,其中BO到VO部分,可能都需要前端参著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net与。而这些,就是前端数据层需要考虑解决的转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】问题。

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】【转载请注明来源】本文作者:唐霜,转载请注明出处。

正如前文提到过,本文作者:唐霜,转载请注明出处。数据层生产数据,视图层消费数据【版权所有,侵权必究】【转载请注明来源】

著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】原创内容,盗版必究。

与此同时,前端还有一个非常棘手的问题,就本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。是人机交互。在所有有关数据的流程模式的讨【作者:唐霜】本文版权归作者所有,未经授权不得转载。论中,很少有人能够将人机交互所带来的数据原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。问题解释清楚。这也是为什么我在《Robu【原创内容,转载请注明出处】【转载请注明来源】st》第15期提出了“事件流”这一层的原原创内容,盗版必究。【转载请注明来源】因(也给自己挖了一个坑)。现在,我要提出【未经授权禁止转载】【原创内容,转载请注明出处】的问题是:用户操作视图所产生的数据,例如本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。键盘输入,鼠标拖动输入,是属于数据源,还【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。是属于运行时数据?

本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】

数据源是固定的(相对而言),而运行时数据【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net是动态的。人机交互中,用户产生的运行时数【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。据,理论上是固定的,因为人输入的内容在那本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。一时刻确定了,不会有变化。但是,实际生产【作者:唐霜】转载请注明出处:www.tangshuang.net中,这类数据生命周期太短了,它们几乎一瞬著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net间就转化为视图状态数据,反映到界面上,成【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。为视图的一部分,然后它们本身就消失了。因转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】此,从这个点上,我虽然认可用户输入的信息【版权所有】唐霜 www.tangshuang.net【本文受版权保护】是数据源,但真正在我们使用时,却是以运行未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net时数据(视图状态)在使用。因此,这类人机著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net交互产生的数据不属于前端数据层管辖范围(原创内容,盗版必究。转载请注明出处:www.tangshuang.net不是由数据层生产),但却可能要发送到服务【转载请注明来源】【作者:唐霜】端,成为新的数据源。那么,在真正的数据层【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。和视图层之间,似乎是少了什么东西,用以在【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net视图层和数据层之间有一个缓冲,以解决这类本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】状态数据反向流回数据源的问题。而这一层,【未经授权禁止转载】本文作者:唐霜,转载请注明出处。我称之为“逻辑层”(并非我所发明,网上早本文作者:唐霜,转载请注明出处。【转载请注明来源】有人这样称呼)。

本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】

本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【作者:唐霜】

逻辑层的主要作用是调度,将数据层的结果实原创内容,盗版必究。转载请注明出处:www.tangshuang.net例化为运行时数据,这些运行时数据将被作为未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。视图状态,用于渲染到界面中。同时,它接收未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。人机交互信号,调度状态变化,协调视图层各本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】个部分做出响应。于此同时,它还可能将状态【本文首发于唐霜的博客】【作者:唐霜】数据转化为实体数据,通过调用数据层通道,本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net将数据发送回源头,并获取新数据,以再次完本文作者:唐霜,转载请注明出处。原创内容,盗版必究。成向视图层输送数据原料的任务。所以,数据层处理原始数据,逻辑层生产运行时数据【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net,视图层消费运行时数据【原创内容,转载请注明出处】

【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net

【作者:唐霜】【原创内容,转载请注明出处】【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。

而逻辑层接收视图层信号的方式,在前端领域【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。非常独特,它通过事件绑定,监听用户对界面【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】的操作,从事件中提取信息,并将事件信息经【版权所有,侵权必究】【版权所有,侵权必究】过一通演变之后,转化为新的数据。在这方面【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.netrxjs这个库做的惟妙惟肖,它可以通过流本文作者:唐霜,转载请注明出处。【转载请注明来源】式管道的形式,将事件信息,转化为状态数据【本文首发于唐霜的博客】【本文首发于唐霜的博客】,并将该数据反馈给状态管理器。由于现代前未经授权,禁止复制转载。原创内容,盗版必究。端编程深受“状态驱动视图”思想的影响,所本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。以,一旦状态接收到新的变化后,会立即反馈【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。到界面上。所以我反复提到,状态管理器,是转载请注明出处:www.tangshuang.net【本文受版权保护】用于控制界面的工具,属于视图层编程。

【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【本文受版权保护】转载请注明出处:www.tangshuang.net

【未经授权禁止转载】【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。

一旦理解了这一点,我们就会发现,如今大红著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】大紫的前端框架领域,更多的是以界面出发,【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】围绕视图层编程,解决一系列人机交互问题。本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】而在数据层,也就是最贴近我们真实业务的层【原创内容,转载请注明出处】【转载请注明来源】面,却几乎毫无建树。这也是为什么我们虽然【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。已经有了强大的框架,却往往还是不断写出结转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。构复杂,条理混乱,不易维护,升级艰难的前转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net端项目。框架只是在技术层面帮助我们确定编程范式,著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net却无法为我们解决真实业务的逻辑梳理。

转载请注明出处:www.tangshuang.net【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。【作者:唐霜】【本文首发于唐霜的博客】

我们纵观围绕业务系统而开发的前端框架,数【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】据层、逻辑层、视图层作为前端最基本的分层本文作者:唐霜,转载请注明出处。【转载请注明来源】结构呼之欲出。其中,视图层非常清晰,因为【原创不易,请尊重版权】【转载请注明来源】我们已经经历了太多视图层框架。逻辑层相对转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】比较混乱,不过如果非得要找到对应的,我们原创内容,盗版必究。【版权所有,侵权必究】姑且认为angular中的control原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】ler编程属于逻辑层编程。而数据层,则在【原创不易,请尊重版权】原创内容,盗版必究。少数企业内部有自己的实践,目前业界还没有【未经授权禁止转载】原创内容,盗版必究。统一的定论。

原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。【转载请注明来源】【原创不易,请尊重版权】【本文受版权保护】

前端数据层【转载请注明来源】

【本文首发于唐霜的博客】【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。【本文受版权保护】本文版权归作者所有,未经授权不得转载。

从上文的描述中可以看出,我们所指的数据层本文作者:唐霜,转载请注明出处。原创内容,盗版必究。是指处理、管理静态数据资源的编程层,而非【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。动态的运行时编程层。数据层的编程,形象的本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】说,我们是在进行“壳”的编程,这个“壳”著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。本质目标是为运行时数据塑形,使得运行时数【本文受版权保护】【原创内容,转载请注明出处】据自身内部拥有某种约束性,以供逻辑层、视【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net图层使用时,符合业务的实际。数据层本身也转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。是分层的,它主要有服务层和模型层组成。

【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。【作者:唐霜】【原创不易,请尊重版权】

服务层【本文首发于唐霜的博客】

原创内容,盗版必究。【版权所有,侵权必究】原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】

关于前端Service层的讨论并不少,一【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】般认为,前端和后端的数据交互层被称为Se本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】rvice层,也就是通过ajax拉取和发【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net送数据到后端API接口的这一层。不过我认本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】为这种理解过于简单,它所蕴含的内在意义没原创内容,盗版必究。【原创不易,请尊重版权】有被讲透,无法让读者深刻理解从数据源获取【未经授权禁止转载】转载请注明出处:www.tangshuang.net的数据与应用本身之间的关系。

原创内容,盗版必究。未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】

在这里,我将引入“数据仓库”设计中的分层原创内容,盗版必究。【版权所有,侵权必究】相关知识来阐述前端数据服务层。

【本文首发于唐霜的博客】原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】

前文提到,前端数据不是无源之水,前端数据【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。的来源有很多,其中最重要的形式包含API【转载请注明来源】本文版权归作者所有,未经授权不得转载。接口、WebSocket通知、local著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。Storage本地持久化存储。我们设计一【原创不易,请尊重版权】【未经授权禁止转载】种“数据仓库”,它要完成如下的任务:

著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。未经授权,禁止复制转载。【本文受版权保护】
  • 隔离前端应用与数据源,对于前端应用而言,未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。不需要关心和数据源的交互问题,它把数据来著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net源问题委托(代理)给数据仓库,它只从数据【原创不易,请尊重版权】【转载请注明来源】仓库读取数据,或提交数据,它只和数据仓库【未经授权禁止转载】本文作者:唐霜,转载请注明出处。交互,而不和真正的数据源直接交互,甚至它【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】不需要关心数据背后真正的数据源,不需要关著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。心有没有数据源,这一层被数据仓库接管了,未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。对于应用而言,数据源是黑盒。
  • 【本文受版权保护】本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。
  • 数据仓库不仅要向应用提供数据,同时还要反转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。应数据变化,也就是通知应用数据已经发生变【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】化,应用应该做出相应的变化(如重新渲染)【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。,这里我们可以使用观察者模式完成。
  • 【版权所有,侵权必究】原创内容,盗版必究。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】
  • 数据仓库自己本身要解决数据的本地化,也就【版权所有,侵权必究】【作者:唐霜】是根据前端应用的需求,完成数据的缓存、本【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。地持久化等,比如某些应用的数据,要求刷新原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。页面后,之前的数据还在,而不是需要从服务【作者:唐霜】著作权归作者所有,禁止商业用途转载。端再次拉取全部数据。
  • 【作者:唐霜】【本文受版权保护】本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】
  • 数据仓库自己要有和服务端实时交互的能力,转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。无论是通过websocket还是其他方式原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】,完成前端应用数据提交时,组建请求队列,【原创内容,转载请注明出处】【未经授权禁止转载】和服务端交互。如果是提交数据,还要在服务【作者:唐霜】原创内容,盗版必究。端数据更新之后,主动拉取回新数据,并通知【原创不易,请尊重版权】【作者:唐霜】前端应用这一变化。
  • 【作者:唐霜】转载请注明出处:www.tangshuang.net【作者:唐霜】本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】

总而言之,数据仓库的存在,隔离了前端应用【转载请注明来源】【原创内容,转载请注明出处】和服务端,对于前端应用而言,服务端应该是转载请注明出处:www.tangshuang.net【本文受版权保护】不可见的,它只会和数据仓库交互,读取和写未经授权,禁止复制转载。【原创内容,转载请注明出处】入数据。

转载请注明出处:www.tangshuang.net【版权所有,侵权必究】【原创内容,转载请注明出处】未经授权,禁止复制转载。

虽然数据仓库分层的方法不同,但是大体上,【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。数据仓库设计主要可以分为如下几层。

著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。本文作者:唐霜,转载请注明出处。

未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】

虽然不同文献中对数据仓库分层阐述不同,但未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】我总结认为,主要如上图5层。

【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【作者:唐霜】【本文受版权保护】著作权归作者所有,禁止商业用途转载。
  • Source:数据源层,本质上它不属于数著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】据仓库本身,而是数据仓库的上游,数据仓库原创内容,盗版必究。未经授权,禁止复制转载。的数据从这里来。
  • 本文版权归作者所有,未经授权不得转载。【本文受版权保护】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。
  • ODS (Operational Dat【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.neta Store):操作数据存储层,即将数未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net据原子化存储,是静态的,固定的,不是运行【本文受版权保护】原创内容,盗版必究。时的,对于前端而言,ODS可以落实到in【本文受版权保护】【转载请注明来源】dexedDB中管理数据,当然也可以直接转载请注明出处:www.tangshuang.net【本文受版权保护】放在内存中,刷新页面再重新从服务端读取,【未经授权禁止转载】未经授权,禁止复制转载。但是,在js运行中,不应该对ODS中的数【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】据进行任何修改,它应该是静止的,除非来自【版权所有】唐霜 www.tangshuang.net【转载请注明来源】服务端的新数据替换了原始老数据。
  • 【作者:唐霜】【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。
  • DW (Data Warehouse):原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。数据仓库层,这里的数据仓库主要指代码层面未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net,如何对ODS进行组织和管理,它更多的是本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net负责对数据仓库中的数据进行变化、转化、修原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】饰,并管理好存储在ODS中的数据,起到存【未经授权禁止转载】【转载请注明来源】储器的管理程序的作用。DW层本身可以有多【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。个层组成:
    • DWD (Data Warehouse 著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】Detail):明细层,距离ODS最近,【本文受版权保护】【关注微信公众号:wwwtangshuangnet】是对ODS的详细描述和补充
    • 【作者:唐霜】【转载请注明来源】【关注微信公众号:wwwtangshuangnet】
    • DWB (Data Warehouse 【本文首发于唐霜的博客】【转载请注明来源】Basis):基础层,也叫轻度汇总层,主本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net要完成数据的统计、清洗等工作
    • 【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】原创内容,盗版必究。【版权所有,侵权必究】【版权所有,侵权必究】
    • DWS (Data Warehouse 【版权所有,侵权必究】【原创不易,请尊重版权】Service):汇总层,距离DM层最近【版权所有,侵权必究】原创内容,盗版必究。,为DM层准备数据
    • 本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。
    • DIM:字典层,为数据仓库提供字典配置,【转载请注明来源】【转载请注明来源】例如黑白名单等
    • 【原创不易,请尊重版权】【原创不易,请尊重版权】【本文受版权保护】
  • 本文作者:唐霜,转载请注明出处。【转载请注明来源】本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net
  • DM (Data Market):数据集转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net市层,对数据进行包装,向下一层提供符合具【原创不易,请尊重版权】【本文首发于唐霜的博客】体使用场景所需要的结构的数据。
  • 【转载请注明来源】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】
  • APP:应用层,也就是真正使用数据的一层【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】,本质上也不属于数据仓库的部分,而是数据本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net仓库的使用者,也就是我们的前端应用本身。
  • 原创内容,盗版必究。本文作者:唐霜,转载请注明出处。【作者:唐霜】著作权归作者所有,禁止商业用途转载。

在后端设计数据仓库时,需要对每一层都创建【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net数据库以保持每一层的数据,但是在前端,为未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net了节省,我们可以只在ODS存储数据,其他【转载请注明来源】【版权所有,侵权必究】层都是基于已有数据进行现算。而且对于前端本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net应用而言,DW和DM是可以合并的,我们不本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。需要将职能划分的如此清楚,总体而言,我们本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。只需要一个DS(Data Service【原创内容,转载请注明出处】【原创不易,请尊重版权】)层,用以从ODS中读取原始数据,然后格本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】式化为具体业务逻辑中需要的格式化数据。

【转载请注明来源】本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】【版权所有,侵权必究】

此外,我们发现,从Service到Sou未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。rce这个中间,其实要处理很多事情,其中【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net需要包含数据的拉取、发送、同步,以及数据未经授权,禁止复制转载。【本文受版权保护】的存储,这些事都要完成。除此之外,还要完本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。成两个可选的事:从数据源拉取的数据,可能【本文首发于唐霜的博客】未经授权,禁止复制转载。需要经过格式化之后,再存储在本地;发送的【转载请注明来源】【版权所有,侵权必究】数据,可能需要经过一定转化后才向服务端同【版权所有】唐霜 www.tangshuang.net【转载请注明来源】步。我在几年前就开始实现一个叫 databaxe【访问 www.tangshuang.net 获取更多精彩内容】 的库,这个库在实现之初我并没有接触数据【转载请注明来源】【版权所有】唐霜 www.tangshuang.net仓库的知识,凭借自己的直觉完成它的设计和著作权归作者所有,禁止商业用途转载。【本文受版权保护】开发,后来发现,它在很多方面符合数据仓库【关注微信公众号:wwwtangshuangnet】【作者:唐霜】的设计理念。

本文作者:唐霜,转载请注明出处。【作者:唐霜】【作者:唐霜】【版权所有】唐霜 www.tangshuang.net

【本文首发于唐霜的博客】【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】【本文受版权保护】本文作者:唐霜,转载请注明出处。

上图阐述了正常数据从数据源,到应用的整个本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。过程,中间环节就是数据仓库完成的事。其中著作权归作者所有,禁止商业用途转载。【作者:唐霜】,“同步”这个操作比较特殊,由于前端应用【版权所有,侵权必究】【原创不易,请尊重版权】需要通过http等方式从服务端拉取数据,【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】一旦服务端数据发生变化,例如当前这个用户【转载请注明来源】本文作者:唐霜,转载请注明出处。现在在PC上进行操作,但是中间有一个环节【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】,他去手机APP上处理了,这个时候,他再本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】看PC,我们应该将他在APP上的操作同步转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】到PC中,而这个工作,可以通过webso【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】cket完成同步。

【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。

另外,在上图中没有特别注明的是前端特有的【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】事件驱动,当websocket下发用户在【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。手机端的操作信息后,如何将新的数据反馈到【本文首发于唐霜的博客】【本文受版权保护】界面上呢?在数据仓库设计时,需要APP层【版权所有,侵权必究】未经授权,禁止复制转载。通过观察者模式,对数据仓库中数据的变化进未经授权,禁止复制转载。【本文受版权保护】行订阅,当数据仓库同步数据变化之后,调用转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。APP层传入的subscribe函数,从【版权所有,侵权必究】原创内容,盗版必究。而触发APP层的重新渲染。

转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

模型层本文作者:唐霜,转载请注明出处。

原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】【原创内容,转载请注明出处】原创内容,盗版必究。

Service层为我们解决了数据源的抽象【本文受版权保护】【作者:唐霜】,但是感觉前端应用整体层面仍然少了什么,【转载请注明来源】【本文首发于唐霜的博客】因为对于我们而言Service层是可选的【转载请注明来源】【原创内容,转载请注明出处】,其设计复杂程度也是可选的,应用可以不要著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.netService,或者Service仅仅是未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。一个ajax接口请求的封装,而不需要上述原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。所讲的从ODS到DM的设计,这也是可行的转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。,而且也是当下大部分前端应用实践的。然而【未经授权禁止转载】【本文首发于唐霜的博客】,我们究竟少了什么?

【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。未经授权,禁止复制转载。

我们少了一层模型层。【本文受版权保护】

本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【原创内容,转载请注明出处】

M和VM的区别著作权归作者所有,禁止商业用途转载。

【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】未经授权,禁止复制转载。

以Angular、Vue为典型代表的框架【作者:唐霜】原创内容,盗版必究。声称自己是MVVM框架,那么这里的M和V转载请注明出处:www.tangshuang.net【版权所有,侵权必究】M的区别究竟在哪儿呢?从字面上看View【转载请注明来源】原创内容,盗版必究。Model看上去好像本身就是一种Mode本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netl,但实质上完全不一样。我们用代码来说明本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】

未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。【转载请注明来源】
const Person = Vue.extend({
  template: `
    <div>
      <span>{{name}}</span>
      <span>{{age}}</span>
    </div>
  `,
  data() {
    return {
      name: 'some',
      age: 10,
    }
  },
  methods: {
    getName() {
      return this.name
    },
    setAge(age) {
      this.age = age
    },
  },
})

这是用Vue定义的一个ViewModel本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】,它本质上是在创建一个视图模型,它确实和本文作者:唐霜,转载请注明出处。原创内容,盗版必究。模型一脉相承,但是,它的核心在于围绕te【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】mplate描述视图,模型上规定的属性、【版权所有,侵权必究】【原创不易,请尊重版权】方法,全部在视图中使用。

未经授权,禁止复制转载。未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。
class Good {
  type = ''
  price = 0
  storage_count = 0

  up(count) {
    this.storage_count += count
  }
  down(count) {
     this.storage_count -= count
  }
}

这是一个描述商品的简易模型,它描述了作为转载请注明出处:www.tangshuang.net【作者:唐霜】一个商品,应该具备什么属性,可以进行什么【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net操作。和Person的最大区别在于,Go【本文受版权保护】本文版权归作者所有,未经授权不得转载。od模型只描述自身,而Person却描述本文作者:唐霜,转载请注明出处。原创内容,盗版必究。它要用template生成的界面。Vie本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。wModel是自洽的,它定义的属性、方法转载请注明出处:www.tangshuang.net【版权所有,侵权必究】,大部分情况下会在template中直接转载请注明出处:www.tangshuang.net【版权所有,侵权必究】使用,阅读ViewModel的描述是可以原创内容,盗版必究。【本文受版权保护】对视图逻辑有完整闭环的印象的。但是Mod未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。el是开放的,Model上定义好的属性、转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。方法,你根本不知道它会在哪里被调用,是在【转载请注明来源】著作权归作者所有,禁止商业用途转载。什么情境下,按什么顺序被调用。所以,Vi原创内容,盗版必究。未经授权,禁止复制转载。ewModel看上去是Model,但本质【作者:唐霜】【本文首发于唐霜的博客】上又不是Model。

【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。

在前端系统中,界面必不可少,所以View转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】Model有其价值,特别是以“状态驱动视著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。图”的思想盛行后,View和ViewMo未经授权,禁止复制转载。【原创内容,转载请注明出处】del的组合可以实现极高的编程效率,对视【转载请注明来源】转载请注明出处:www.tangshuang.net图的抽象也变得非常优秀。然而,如果单纯这【转载请注明来源】【版权所有】唐霜 www.tangshuang.net样,就可以声称自己是完整的框架,那么,我转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net很遗憾的说:这不过只是完整的VVM框架,前面的M被干本文版权归作者所有,未经授权不得转载。【转载请注明来源】掉了。而且,对于框架本身而言,基于ViewM转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。odel的驱动确实不错,却不是唯一的选择著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】,React本身是不基于VM的,或者说R【转载请注明来源】【原创内容,转载请注明出处】eact并不强调是基于VM的,而是说自己原创内容,盗版必究。【本文首发于唐霜的博客】是基于State的。这很好理解,因为在R【本文首发于唐霜的博客】【原创内容,转载请注明出处】eact中,你不需要事先定义一个View本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。Model就可以完成界面编程,这也是为什【作者:唐霜】【版权所有,侵权必究】么React称自己是纯UI库,而不像Vu著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】e称自己为框架。

【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】【作者:唐霜】

从前文我关于前端分层结构的描述来看,我更【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。倾向于把拥有完整MVP(而非MVVM)的【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。框架称为完整的前端框架。其中V层业界已经本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。很成熟了,而P层勉强可以通过我们自己的各著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。种骚操作结合框架特征完成,唯独M层,业界【未经授权禁止转载】原创内容,盗版必究。没有统一认识。

【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net

前端需要模型吗?原创内容,盗版必究。

【作者:唐霜】未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】

如果VVM框架已经可以帮我们解决问题了,【转载请注明来源】本文作者:唐霜,转载请注明出处。那么我们确实不需要模型层。然而,很多前端【版权所有,侵权必究】原创内容,盗版必究。开发者和我一样,经历过刚开始用Vue的时【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。候大喊爽,但当业务需求稍微多一些,复杂一【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net些,就会跪下来拜求不要摩擦。这是为什么呢【关注微信公众号:wwwtangshuangnet】【作者:唐霜】

本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【原创不易,请尊重版权】

因为我们将复杂的业务逻辑写在ViewMo【本文首发于唐霜的博客】原创内容,盗版必究。del中,我们错误的认为ViewMode【作者:唐霜】【本文受版权保护】l可以承载视图模型和业务模型。可是实际上【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。,别说承载业务,单纯一个页面拥有极其复杂【作者:唐霜】未经授权,禁止复制转载。的交互的时候,VM管理自己的视图交互逻辑【原创不易,请尊重版权】【本文受版权保护】都顾犹不及,怎么可能还能包揽业务的逻辑呢【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。

【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net

那么,一旦有一天,当你可以明确区分,某个【作者:唐霜】【转载请注明来源】操作应该属于业务层面,某个操作应该属于交【版权所有,侵权必究】【未经授权禁止转载】互层面,而且,这些操作混在一起带来管理麻【转载请注明来源】著作权归作者所有,禁止商业用途转载。烦的时候,你就可以准备创建自己的前端数据未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net模型了。对于我个人而言,由于经历的几套大未经授权,禁止复制转载。【本文首发于唐霜的博客】系统都是业务层面的,所以很容易区分业务系【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net统和功能型应用。只要一开始就发现这是一个【本文首发于唐霜的博客】【版权所有,侵权必究】业务开发,我就会不自觉的提炼出业务实体,【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。将业务逻辑收拢在模型中。

本文作者:唐霜,转载请注明出处。【转载请注明来源】【作者:唐霜】【本文受版权保护】原创内容,盗版必究。

DDD领域驱动设计转载请注明出处:www.tangshuang.net

本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【版权所有,侵权必究】

讨论数据模型,绝对离不开DDD这个话题。未经授权,禁止复制转载。【未经授权禁止转载】并非凑热度,而是因为DDD为我们提供了方【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。法论,帮助我们快速理解如何去设计领域模型著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】,有了这些方法论,我们可以提前避免掉一些本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。坑,不需要自己摸索太多。不过遗憾的是,D【作者:唐霜】【关注微信公众号:wwwtangshuangnet】DD只为我们提供了思维层面的方法论,却在【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net实际编程领域没有太多可直接使用的内容,开著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net发者习得DDD思想之后,还需要依靠自己对著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。业务本身的理解,以及自身在行业中的经验来【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。构建自己的领域模型和业务系统。

【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。【本文受版权保护】

虽然在具体意义上有差别,但是我们可以将领本文作者:唐霜,转载请注明出处。原创内容,盗版必究。域模型和我们所指的前端数据模型划等号,都【本文受版权保护】【版权所有,侵权必究】是对业务实体的抽象描述。DDD给我们的最【作者:唐霜】【原创不易,请尊重版权】大启发在于,我们不单单要关心数据,而且要关心业务本文作者:唐霜,转载请注明出处。。开发层面,DDD给我们提出了三个核心对本文作者:唐霜,转载请注明出处。【转载请注明来源】象:

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】【转载请注明来源】
  • 实体:用于描述业务的对象【原创内容,转载请注明出处】
  • 未经授权,禁止复制转载。【本文受版权保护】著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。
  • 事件:用于描述状态变化信息的对象原创内容,盗版必究。
  • 转载请注明出处:www.tangshuang.net原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】
  • 服务:用于执行无状态更新的函数集合未经授权,禁止复制转载。
  • 本文版权归作者所有,未经授权不得转载。【转载请注明来源】未经授权,禁止复制转载。

其中,实体(Entity)是领域模型的核本文作者:唐霜,转载请注明出处。【作者:唐霜】心,一个Entity是对单个业务进行描述【作者:唐霜】未经授权,禁止复制转载。的完整信息集合。这里“完整”是指该业务中本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】将拥有那些状态,以及将会发生什么事情。简原创内容,盗版必究。原创内容,盗版必究。单讲,Entity包含了业务对象的能力,原创内容,盗版必究。转载请注明出处:www.tangshuang.net本质上就是描述这个业务都拥有哪些特征,以本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。及内部的约束逻辑。

【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。

在前端语境下,领域模型在代码层面,就是一本文作者:唐霜,转载请注明出处。【转载请注明来源】个class类(当然,这是从java的面【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。向对象过来的)。而这个Model类需要包【转载请注明来源】著作权归作者所有,禁止商业用途转载。含对实体的描述,需要实现事件系统,必要的转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】时候需要实现服务(用静态属性即可)。我们【作者:唐霜】本文作者:唐霜,转载请注明出处。来看一个例子:

【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【版权所有,侵权必究】
class Good {
  type = ''
  price = 0

  #events = []
  
  increasePrice(num) {
    this.price += num
    this.#events.forEach((item) => {
      const { type, fn } = item
      if (type === 'priceIncreased') {
        fn()
      }
    }) 
  }

  onPriceIncreased(fn) {
    this.#events.push({
      type: 'priceIncreased',
      fn,
    })
  }

  static create(data) {
    const { type, price } = data
    const instance = new this()
    instance.type = type
    instance.price = price
    return instance
  }
}

这是一个针对Good的纯业务模型,不涉及未经授权,禁止复制转载。原创内容,盗版必究。任何和界面相关的信息。它包含了实体信息t著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】ype, price, increase【本文受版权保护】著作权归作者所有,禁止商业用途转载。Price,也包含了事件系统#event原创内容,盗版必究。【未经授权禁止转载】,还包含了用于创建Good实例的服务cr未经授权,禁止复制转载。转载请注明出处:www.tangshuang.neteate。在VM中,它可能被使用:

【未经授权禁止转载】未经授权,禁止复制转载。【本文首发于唐霜的博客】原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。
const good = Good.create({
  type: 'ball',
  price: 12.5,
})

good可能被用于界面上某处的渲染【版权所有】唐霜 www.tangshuang.netvm.good = good,此时的原创内容,盗版必究。good和Good已经脱离了模型,成为运行时的状著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。态,可以作为状态在视图中使用了。

【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】

某些情况下,一个模型的实例可能包含另外一本文版权归作者所有,未经授权不得转载。【作者:唐霜】个模型的实例,此时,模型之间就产生了依赖【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。关系。例如

【本文受版权保护】本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。
class Shop {
  goods = []
  addGood(data, count) {
    for (let i = count; i --;) {
      const good = Good.create(data)
      this.goods.push(good)
    }
  }
}

这是一个商铺模型,一个商铺中可能包含一堆著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】商品,通过addGood方法向商铺中添加未经授权,禁止复制转载。【原创内容,转载请注明出处】商品,该店铺有哪些商品都被放在goods【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。属性中。但是这里有一个问题,如果我们要从【原创不易,请尊重版权】原创内容,盗版必究。商铺下架一个商品怎么办?能不能直接在Go转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netod中加一个下架的方法呀,这样我不需要调【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。用Shop的方法,而是可以直接对Good著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。实例进行操作?虽然实践层面这是可行的,但著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】是我们不允许这么设计。Clean Arc【作者:唐霜】著作权归作者所有,禁止商业用途转载。hitecture 提供了一种有关数据分【本文受版权保护】本文版权归作者所有,未经授权不得转载。层的设计,我所在意的是,它提供了依赖指向著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】性理论,外层实体依赖内层实体,因此,对于【本文受版权保护】【关注微信公众号:wwwtangshuangnet】内层的实体,不需要知道外层实体对它的需求【本文受版权保护】【本文受版权保护】如果在设计时,内层实体还要考虑外层如何使未经授权,禁止复制转载。【未经授权禁止转载】用它,那么这是“不干净”的架构。对于领域模型而言,它所要描述的是自身所拥【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net有的特征和能力,描述时,不需要,也不应该【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。考虑外部环境,它被谁使用,如何使用,对于未经授权,禁止复制转载。【作者:唐霜】它本身而言并不需要关系。领域模型是对业务对象的纯粹描述,和业务运本文版权归作者所有,未经授权不得转载。【作者:唐霜】行过程中的环境无关。

【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。

流程模型【本文首发于唐霜的博客】

转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。

实体模型往往是对某个具体的事物进行抽象描【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】述,但是业务系统中另一个更复杂的对象就是转载请注明出处:www.tangshuang.net原创内容,盗版必究。流程。比如办公系统中的审批流,比如电商系【本文受版权保护】【未经授权禁止转载】统中的订单流程,这些流程不指具体的某个事【本文首发于唐霜的博客】【原创不易,请尊重版权】物,而是一系列实体、行为和逻辑的总和。

【未经授权禁止转载】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。未经授权,禁止复制转载。

实际上,转载请注明出处:www.tangshuang.net流程的本质,是业务时间内实体的进出和实体本文作者:唐霜,转载请注明出处。【作者:唐霜】状态的变化的总和。实体的进出是指,在流程这个“业务池”中【原创内容,转载请注明出处】【原创内容,转载请注明出处】,不同阶段,新的实体进来,老的实体出去,【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】例如订单流程中,配送阶段,配送员这个实体【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】进来,完成配送之后,配送员这个实体出去。【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】而用户付款,则会修改订单的状态。业务池对本文作者:唐霜,转载请注明出处。【转载请注明来源】付款实体状态变化抛出的事件进行监听,得到著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。事件信息之后,再做一轮其他状态变化或实体【原创不易,请尊重版权】【原创内容,转载请注明出处】进出。事件是保证业务流程形成链状,持续更转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net迭的关键。

【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】【原创内容,转载请注明出处】

一个描述用户申请开通博客的流程,【版权所有,侵权必究】来自网络原创内容,盗版必究。

【原创不易,请尊重版权】【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net

方框圈的是核心业务,圆形圈的是实体的状态著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】变化,核心业务一般包含在最简单的描述中,未经授权,禁止复制转载。【作者:唐霜】业务流程一般是不会发生变化的,变化的是核【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net心业务。流程本身,实际上是由命令式代码根转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。据复杂的条件判断完成的一系列指令。这些指本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net令中,部分包含了对业务实体的操作,一般而本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。言是通过调用流程中业务实体模型实例的方法【版权所有,侵权必究】【作者:唐霜】完成的。模型本身只描述了自身的能力,但是【原创不易,请尊重版权】【原创不易,请尊重版权】这些能力在流程中如何被使用,使用时先后顺未经授权,禁止复制转载。【未经授权禁止转载】序是什么,都是由流程模型所决定的。在我已【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。有的经验中,根本还没有实践过流程模型,我著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net大部分业务逻辑中,都是杂糅在框架编程中,【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。也就是angular的controlle【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。r,或vue的组件method中。虽然我原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】没有自己实践过,但是很明显,如果我们拥有【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net一个流程模型,那么就像领域模型一样,将大【未经授权禁止转载】【原创内容,转载请注明出处】大提升我们对业务本身的理解。而且,上文一原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net直没有提到的一个点是,界面测试是比较麻烦【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】的,但是模型的测试却相对来说比较容易,如【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】果我们能抽象出流程模型,那么针对流程的测著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。试撰写,将成为可能。

【本文受版权保护】转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net

模型元【关注微信公众号:wwwtangshuangnet】

【原创内容,转载请注明出处】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】

不过,在前端语境下,纯粹静态的领域模型有【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。的时候会带来一些问题。我们在描述一个实体【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。的时候,我们往往发现,模型中我们需要加入【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】一些辅助信息才能完成前端编程的需要,而这【原创内容,转载请注明出处】【作者:唐霜】些辅助信息不是业务核心的信息,不过理论上【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net讲,也确实是和业务实体相关的信息。应对这【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】种辅助信息,如果你加上,又会让模型含有杂【本文受版权保护】【作者:唐霜】质,但是不加,又在实际编码时会遇上麻烦,本文作者:唐霜,转载请注明出处。原创内容,盗版必究。这是一块烫手山芋。不过我的想法是,凡事必有特殊,我们遵循DDD,并不意味着【本文首发于唐霜的博客】【未经授权禁止转载】DDD必须原模原样的在前端实现。DDD的最佳实践都是针对后端的,后端开原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。发存在的特征,前端可能不存在,前端的特征著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】,后端也可能不存在,因此,以DDD为设计本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】思想,同时针对前端特殊性做出一些调整,也【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。是应该的。

本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【转载请注明来源】本文作者:唐霜,转载请注明出处。

我花费了很长一段实践撰写前端模型库 【转载请注明来源】tyshemo【本文首发于唐霜的博客】,它的主要目标,是为前端提供创建读写过程【原创不易,请尊重版权】原创内容,盗版必究。具有强约束的模型的能力。在 tyshem原创内容,盗版必究。【转载请注明来源】o 的实践中,你需要定义模型上的字段,而本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net对字段的定义,我称之为Meta。

本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【版权所有,侵权必究】【本文首发于唐霜的博客】
import { Meta } from 'tyshemo'

class Name extends Meta {
  static default = ''
  static type = String
  static required = true
  static as = 'name'
}

我通过一段简短的代码定义了一个名字为Na转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netme的Meta,它将在模型中作为一个字段转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net的定义。比如,我的一个模型中有一个字段n本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.netame,它将被Name所定义:

原创内容,盗版必究。【本文受版权保护】【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。
import { Model } from 'tyshemo'

class Person extends Model {
  static name = Name
}

一般而言,一堆Meta只为一个Model本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】服务,很少有跨模型共用Meta的情况。不未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。过也有例外,由于我们的应用可能存在于PC未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。和APP两端,而在一些具体逻辑上,同一个原创内容,盗版必究。【本文受版权保护】字段可能又存在不同逻辑,所以,我们可能同未经授权,禁止复制转载。【转载请注明来源】样是定义Person模型,但为了满足不同【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】端的逻辑需求,我们会定义两个Person原创内容,盗版必究。【原创不易,请尊重版权】模型,在不同端使用自己对应的那一个。本质【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】上,这两个Person模型是代表同一个业【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。务实体,但是却因为前端的特殊性,它们在具本文版权归作者所有,未经授权不得转载。【转载请注明来源】体字段上会有不同。

【作者:唐霜】【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】
// for PC
class Person extends Model {
  static name = Name
  static weight = WeightOfPc
}

// for Mobile
class Person extends Model {
  static name = Name
  static weight = WeightOfMobile
}

上面这两个模型,我们就共用了同一个Nam本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。e Meta,但是在weight字段上,【作者:唐霜】【原创不易,请尊重版权】我们用了不同的Meta。不过从业务上讲,本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】虽然两个weight的Meta不同,但是本文版权归作者所有,未经授权不得转载。【作者:唐霜】对于Person而言,它是相同的,在设计【关注微信公众号:wwwtangshuangnet】【本文受版权保护】该模型时,应该保持相同的API接口,以保本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net证在不同端,它的用法是一致的。只是说,在本文作者:唐霜,转载请注明出处。原创内容,盗版必究。运行时,weight字段会存在少许的不同未经授权,禁止复制转载。【本文首发于唐霜的博客】,不过理论上,这种不同也应该是提前设计好本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】的,后端应该根据这种不同制定不同的策略。

【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】

运行时数据层本文作者:唐霜,转载请注明出处。

原创内容,盗版必究。本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。

首先明确,这里所指的运行时数据层,已经和【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。前文所指的“前端数据层”不是一个概念了。【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。运行时数据,在前端语义下,大多是指状态数著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。据,是程序运行所占用的内存(Memory本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】)数据,在逻辑层和视图层进行消费的数据。【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】前端数据层分为Service层和Mode原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.netl层,它们是分离的,Model层可以内置本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。Service层的某些能力,但不是强制的【转载请注明来源】转载请注明出处:www.tangshuang.net,其实大部分情况下,这两个层的融合要靠逻未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net辑层来完成。逻辑层从Service中取出【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】数据,作为初始信息传入模型进行实例化,得【本文受版权保护】【原创不易,请尊重版权】到模型实例,交给视图层使用。逻辑层是将抽未经授权,禁止复制转载。【本文受版权保护】象的静态的数据层进行实例化,得到运行时数【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。据的主要场所。

【未经授权禁止转载】【原创不易,请尊重版权】【原创不易,请尊重版权】原创内容,盗版必究。

【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】

上图中用红色标注的部分,就是我们前端数据【转载请注明来源】原创内容,盗版必究。的转化过程。从API拿到的原始数据,经过未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。Service层汇总处理暂存在前端,形成【本文首发于唐霜的博客】原创内容,盗版必究。持久化数据,这些数据是相对静态的不能被修【版权所有,侵权必究】【转载请注明来源】改的,除非在明确得知服务端数据发生变化的【本文受版权保护】【版权所有】唐霜 www.tangshuang.net情况下,它会被替换为最新的数据。而真正要【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。交给应用层使用时,Service层需要通【原创内容,转载请注明出处】【版权所有,侵权必究】过DM层完成从持久化数据中读出的过程,而【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net在读出之后,它作为数据本身并没有意义,而【转载请注明来源】本文版权归作者所有,未经授权不得转载。是会和模型进行一次结合,实例化模型时,将本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】这些数据作为模型的初始化数据传入,从而得【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】到一个特定状态的模型实例,此时的模型实例【原创不易,请尊重版权】【作者:唐霜】,本质上,是一个内存中的js对象,因此是【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。一个运行时数据。JS运行时数据的一大问题本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。,是无法作为DTO(Data Trans本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.netfer Object)在网络上传输,它无著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】法被直接发送到后端,保存到服务器数据库。著作权归作者所有,禁止商业用途转载。【本文受版权保护】能够作为DTO的,只能是纯对象或文本/b【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.netuffer形式,而这个“纯”会导致模型状著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。态丢失,也就丢失了运行时特征。因此,其中本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net一个环节也很重要,就是Model基类应该【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。具备通过纯数据还原有状态模型实例的能力,【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。这样,我们就可以通过DTO复原当前业务实【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】体(包含状态的模型实例)。

【转载请注明来源】本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】【转载请注明来源】

将Service和Model融合在一起的【原创内容,转载请注明出处】【转载请注明来源】,往往并非数据层本身,而是逻辑层。前文提本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。到,数据层是“壳”的编程,因此,数据层本【本文受版权保护】本文版权归作者所有,未经授权不得转载。身并没有状态,只有逻辑层和视图层才有状态【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net。而视图层功能相对单一,即完成界面渲染。本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。因此,逻辑层承担着将数据层的抽象业务转化【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】为运行时数据状态的重要功能。可以说,逻辑未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】层是数据层的末端,但好像又是整个数据层最【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】终能够产生价值的起点。

本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。【转载请注明来源】

小结原创内容,盗版必究。

【原创不易,请尊重版权】【版权所有,侵权必究】【原创内容,转载请注明出处】

本文详细阐述了我关于前端数据层相关的研究【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。和思考。业务系统前端,可以按照“视图层、【原创不易,请尊重版权】【原创内容,转载请注明出处】逻辑层、数据层”进行结构分层。其中数据层【版权所有,侵权必究】转载请注明出处:www.tangshuang.net在当下的前端领域被讨论的不多,但在我看来原创内容,盗版必究。原创内容,盗版必究。却非常重要。数据层本身也可以分为服务层和【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net模型层,数据从源头(API接口)到数据层【转载请注明来源】未经授权,禁止复制转载。,到逻辑层,到视图层,然后在回流回来,形本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。成一个完整的闭环。

原创内容,盗版必究。【作者:唐霜】【版权所有,侵权必究】转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。

前端数据流总体示意图【转载请注明来源】

本文作者:唐霜,转载请注明出处。【作者:唐霜】未经授权,禁止复制转载。【本文首发于唐霜的博客】

上图囊括了本文所提出的整个前端数据层世界【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】观,前端的数据管理是一个很大的工程,本文【原创不易,请尊重版权】【版权所有,侵权必究】主要着眼于在当下热门框架缺失数据层,却在转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。业务系统中大行其道的现实,反复强调数据层【本文受版权保护】【本文受版权保护】的重要性。但这不代表我不重视状态管理器,【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】以及业务逻辑流程管理等方面的专研。另外,【本文受版权保护】转载请注明出处:www.tangshuang.net本文只在我的个人博客、个人微信公众号、知转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net乎专栏“前端数据治理之道”发表,若经授权未经授权,禁止复制转载。原创内容,盗版必究。转载,会在博客本文下作好链接,否则,全是【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。侵权转载。

【本文受版权保护】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】

我们不能一概而论的说前端所有应用都应该遵【作者:唐霜】【转载请注明来源】循这种设计,文章一开始就着重强调过,我们【本文首发于唐霜的博客】【原创内容,转载请注明出处】只在业务型前端应用中才会面临是否需要在数【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net据层研究更深的问题。业务型,特别是具有流【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】程的业务型系统,我们不仅要关注数据,而且【未经授权禁止转载】【未经授权禁止转载】更要关注真实业务本身,从根本上理解业务实【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。体、规则、逻辑,甚至开发者自己切身去体验转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】一下真实数据环境下业务人员在使用系统时的本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】感受,才能在前端数据层面重新认识系统。我【转载请注明来源】【原创内容,转载请注明出处】不能保证按照本文所述的方法去设计,就一定原创内容,盗版必究。【原创不易,请尊重版权】能写出明晰,不需要重构,逻辑正确,代码易【本文首发于唐霜的博客】原创内容,盗版必究。读的项目,这是我不能保证的。但是,我认为著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。,如果在设计系统之前,如果有过本文所述的本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。所有思考,或许对你的前端代码的设计和管理【转载请注明来源】【版权所有】唐霜 www.tangshuang.net会有帮助。<完>

【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net

2020-07-27 10057

为价值买单,打赏一杯咖啡

本文价值100.57RMB