前端架构:Flux架构初探

最近查找React Transaction的相关资料的时候,无意中看到了Flux这个东西,简单看了一下,突然想到了我以前稍微想过的一个前端架构.

以前是这个想的:

(Controller) ->   (View)

所有关于操作视图的逻辑都单独抽出来,Controller负责处理所有非视图逻辑,这样做的一个好处就是可以将视图部分和逻辑部分分隔开,修改逻辑或者视图并不需要在一堆代码中寻找,只需要找到相应视图变化点,切入修改非常方便.

data=controller.requestData();//获取数据

data=controller.transData(data);

controller.bind(‘click’,view.getButton1(),function(){ controller.doBtn1Click();});//监听

view.renderAll(data);//更新全部视图

view.renderHead(data);//更新头部视图

但这样的一个缺陷就在于大部分关于DTO的逻辑会掺在Controller当中,整个业务逻辑十分不透明,

然后改成了这样:

(Data Model)  ->  (Controller) -> (View)

将数据模型单独抽离出来,Controller部分将更加地清晰

controller.init(); //初始化controller

controller.bind(‘click’,view.getButton1(),function(){ controller.doBtn1Click();});//监听

renderData=dataModel.getData(); //从数据模型获取数据

view.renderAll(renderData);// 完成视图

读了Flux之后,按照这种思想来了一套我所想的Flux

 

其实在前端领域,没有什么真正的所谓的MVC,Flux则从这种MVC的思想框当中跳出来,提出了有一个更适合前端架构的一个架构模型,我也用过类似React的一个前端框架,正如React本身所介绍的那样,React仅仅是一个View层解决方案,如果单使用React代码还是一团糟,其实这种理解是建立在一个范围上的,如果单看View层,React其实已经做到了视图分离,控制器自行去指派各种事件,视图与数据模型的同步也都做得不错,看起来已经像是一个比较小的MVC,但从前端整体看来,这种分离还是不够透彻,各个部分的逻辑还是只能写在render之前,双向数据绑定经常会出现数据不同步的情况(React本身也不支持双向数据绑定),所以最终React只能成为一个View层解决方案.

Flux则提供了一种新的思路,使得数据流向真正的成为了一个单向的过程,这样的一个最好的优点肯定是稳定性要好很多,数据不同步几乎不可能发生(没控制好也可能发生),下面稍微讲一下我理解的Flux架构(有些地方不太一样),所以一下称为这种前端架构.

这种前端架构主要是由Dispatcher,Store,View,Action四部分组成,实际上一切的开始都是Action触发的,所以顺序是Action->Dispatcher->Store->View,但Action的始终还是View,所以我把它放到了最后.

Dispatcher是事件分派器,起初数据仓库里面并没有数据,由事件分派器通过分析事件,将所需的数据列表或者事件发给Store,事件的来源是Action.在Flux中,数据请求是在Action中发送的,但我将这一步移到了Store中,目的是让Store的数据仓库除了具备数据仓库,又具备数据获取的功能.如果可能,前端的数据仓库与后端数据仓库也可以保持1:1的同步状态.

Store是数据仓库,数据仓库包含大部分的DTO逻辑,数据的相关操作是由事件分派器所传出的指令操作的.数据的推送是通过事件,但此时的事件分派器是被弱化的,与Dispatcher不同,是一种属于View的事件机制.

View是视图,所有视图的数据来源都是Store,按照规定,View在任何时刻都不应该主动访问Store去获取数据,而是通过触发Action再通过Dispatcher分配最终间接获取数据,Store也不应该提供对外接口供View访问,这样就可以保证数据的一致性.

为了让整个前端架构的View层更加详细,下面再引入React,扩充View.

State是Store数据与render数据的暂存区,由于React可以保障renderData与State之间的同步关系,所以我们只需要做到State与Store之间的同步关系就可以,这种解决方案就是通过上述的Flux去维持.而中间的React VitrualDOM能使View更加高效灵活.

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注