Linux 之父出席、干货分享、圆桌讨论,精彩尽在 OpenCloudOS 社区开放日,报名戳 了解详情
写点什么

Facebook:MVC 不适合大规模应用,改用 Flux

  • 2014 年 5 月 19 日
  • 本文字数:2535 字

    阅读完需:约 8 分钟

Facebook 认为 MVC 无法满足他们的扩展需求,因此他们决定使用另一种模式:Flux。

在最近 F8 大会黑客之道:重新思考Facebook 的Web 应用开发,Facebook 工程经理Tom Occhino 说,由于他们“非常巨大”的代码库和庞大的组织,“MVC 真的很快就变得非常复杂”,他们得出结论,认为MVC 不适合于大规模应用。每次他们努力增加一项新特性时,系统的复杂性成级数增长,代码变得“脆弱和不可预测”。对于刚接触某个代码库的开发人员来说,这正成为一个严重的问题,因为他们害怕破坏什么东西,不敢动这些代码。其结果是Facebook 的MVC 正在土崩瓦解。

解决这个问题需要“以某种方式使代码结构化,使其更加可预测”。这已经通过 Flux React 完成。Flux 是一个系统架构,用于推进应用中的数据单向流动。根据 Occhino 所述,React 是一个 JavaScript 框架,用于构建“可预期的”和“声明式的”Web 用户界面,它已经使 Facebook 更快地开发 Web 应用。

Facebook 软件工程师 Jing Chen,补充说明 MVC 非常适合小型应用,但是当系统中有很多的模型与相应的视图时,其复杂性就迅速扩大,如下图所示:

根据 Chen 的说法,这样的程序将会非常难以理解和调试,特别是模型与视图间可能存在的双向数据流动,因此提出了以下 Flux 设计:

Store_ 包含了应用的所有数据,Dispatcher_ 替换了原来的 _Controller,当 _Action_ 触发时,决定了 _Store_ 如何更新。当 Store 变化后,View_ 同时被更新,还可以生成一个由 _Dispatcher_ 处理的 _Action。这确保了数据在系统组件间单向流动。当系统有多个 _Store_ 和 _View_ 时,仍可视为只有一个 _Store_ 和一个 _View,因为数据只朝一个方向流动,并且不同的 _Store_ 和 _View_ 之间不会直接影响彼此。

Facebook React 在 GitHub 的页面详细说明了 Flux、Dispatcher_ 和 _Store

Dispatcher 是中心枢纽,管理着 Flux 应用中的所有数据流。它本质上是 Store 的回调注册。每个 Store 注册它自己并提供一个回调函数。当 Dispatcher 响应 Action 时,通过已注册的回调函数,将 Action 提供的数据负载发送给应用中的所有 Store。

随着应用程序的增长,Dispatcher 变得更加关键,因为它将管理 Store 之间的依赖,以特定的顺序调用注册的回调函数。Store 可以声明等待其它 Store 完成更新后,再相应地更新自己⋯⋯

Store 包含应用程序的状态和逻辑。它们的角色某种程度上与传统 MVC 中的 Model 类似,但它们管理很多对象的状态,它们不是某个对象的实例,也不是 Backbone 集合。Store 不只是简单地管理 ORM 风格的对象集合,它还为应用程序中的特定领域(Domain)管理应用状态。

Chen 说,更重要的是在任何其它 Action 触发之前,确保数据层完成视图的更新。当前一个动作还未处理完时,Dispatcher_ 能够拒绝 _Action。对于有其它副作用的动作,例如更新其它视图,这个设计非常有用。它让代码变得更简洁,新开发人员更容易理解也更容易调试。Flux 帮助 Facebook 消除了一个聊天 Bug,该 Bug 提示用户有新消息,但实际上没有。

在 GitHub 上可访问 Flux TodoMVC 教程及其源代码

Facebook 可以使用任何他们觉得合适的设计,但这个问题依旧存在。MVC 适合大规模应用吗?毕竟,有那么多大规模网站。

更新 原文在英文站发布后,许多开发者在 Reddit 上评论 Facebook 的 MVC。以下是一些评论,有些认为 Facebook 误用了 MVC,而另一些则认为他们做了正确的事:

giveupitscrazy

这毫无意义。

其一,他们的 MVC 图形绝对是错的。他们描绘了一个单一控制器处理多个模型,你几乎可以肯定会基于它们交互的 Model 或者逻辑分区来分离控制器。

很显然,他们所描述的这样一个程序无法工作,同时它也不是真正的 MVC。

如果你比较他们的 Flux 图形和真正的 MVC 图形,你就会得出清晰的结论,对 Web 应用来说 MVC 没有任何内在问题。

balefrost

并且⋯⋯事情是这样的⋯⋯他们的 Flux 图与你的 MVC 图非常接近。

他们重新发明了真正的 MVC,然后决定给它一个新名字。哈哈!

hackinthebochs

看起来这个架构将 MVC 变成了某种基于事件的东西。“Store”将它们自己注册到 Dispatcher(可能是任何调用依赖关系),Dispatcher 处理 Action 并确保正确的调用链。这样就将保证正确调用顺序的压力从 Controller 转移到 Dispatcher 和 Store。这将减少改变行为所需的理解。

runvnc

我刚扫了一眼,虽然我不认为自己对这个非常理解,但我理解和同意它的总体思路。

Reddit 用户 jingc09 ,通过她的评论,好像是 Jing Chen,增加了一些回复:

jingc09 :是啊,这是个复杂的幻灯片(那张有多个模型和视图并且双向数据流的片子),部分原因是因为 MVC 究竟是什么没有统一的认识,很多人对它有不同的观点。我们真正想讨论的是双向数据流,数据变化能向后循环并产生级联效应。

她还试图澄清 Flux 的 Dispatcher 不是 MVC Controller:

我想澄清的一件事是,Dispatcher 没有扮演 Controller 同样的角色。Dispatcher 中没有业务逻辑,我们在多个应用中使用相同的 Dispatcher 代码。它只是一个中心枢纽,将事件分发给感兴趣的订阅者(通常是 Store)。但在 Flux 中它是很重要的,因为它强制单向数据流⋯⋯

Wikipedia 关于 MVC Controller 解释

Controller 能发送命令到 Model 去更新 Model 的状态(例如编辑文档)。它也能发送命令到相关的 View 去修改这个 Model 的 View 的展现(例如滚动文档)。

对此, Chen 评论道

Dispatcher 不能做任何这些事,命令必须从其它地方(View、服务器响应和实时更新)传递到 Dispatcher。 https://github.com/facebook/react/blob/master/examples/todomvc-flux/js/dispatcher/Dispatcher.js 也许有助于说明这一点。

根据 Reddit 上的这些评论,关于 MVC 是什么以及应该如何实现,似乎有些混乱。

考虑到 Facebook 对 MVC 的处理,我们有两个观察:

1)第一张幻灯片似乎真的画了太多的 Model 和 View,让人怀疑现实生活中真的有类似的情况吗?Facebook 使用 Flux 解决的问题是一个有 3 个 View 的聊天应用。

2)在他们的 MVC 例子中,为何是 View 产生数据流,从而造成双向流动?同时,在 Flux 图中,为何是 View 产生 Action?View 不应该产生任何东西。View 只是“视图”,没有别的。Facebook 是在误用 MVC 吗?

原文链接: Facebook: MVC Does Not Scale, Use Flux Instead

2014 年 5 月 19 日 02:1328227

评论

发布
暂无评论
发现更多内容

软件设计原则-第二周总结

孙志平

「架构师训练营」第 2 周作业 - 设计原则

森林

程序设计原则

技术小生

极客大学架构师训练营

Week2-总结

TiK

极客大学架构师训练营

架构师训练营-作业-2-架构设计原则

superman

依赖倒置原则

Coder的技术之路

架构师训练营-第二周命题作业

牛牛

极客大学架构师训练营 命题作业

架构师训练营第二周作业

好名字

极客大学架构师训练营 作业

java静态代理与动态代理

张瑞浩

Centos6 内核升级

唯爱

第二周作业

技术小生

极客大学架构师训练营

我写了10年博客,却被人说“不火”?我是这样怼回去的!

王磊

Java 程序人生 「Java 25周年」

架构师训练营第二周总结

sunnywhy

架构师训练营-第二章课程总结-软件设计&面向对象

而立

极客大学架构师训练营

理解持续测试,才算理解DevOps

禅道项目管理

DevOps 测试 持续集成

【架构训练营】第二周作业

Mr.hou

极客大学架构师训练营

第二周课程作业

Geek_a327d3

作业

江帅帅:精通 Spring Boot 系列 03

奈学教育

springboot

CVPR 2020 六小时教程上线!新视角生成的前沿方法

神经星星

人工智能 学习 计算机视觉 模式识别 教程

在滴滴和字节跳动干了 2 年后端开发,太真实…

程序员生活志

程序员 字节跳动 后端 滴滴 开发

Monorepo 原来像陈老师这么香!

admin

Spring Web MVC 依赖倒置原则分析

Arvin

架构设计篇之领域驱动设计(DDD)

小诚信驿站

领域驱动设计 DDD 架构设计 架构设计原则 刘晓成

带功能隔离的cache设计

Coder的技术之路

软件设计原则 - 第二周作业

孙志平

依赖倒置原则联想

极客大学架构师训练营

Week2-作业

TiK

极客大学架构师训练营

嵌入SpreadJS,赋能计量器具检定信息化

葡萄城技术团队

SpreadJS 计量检定

「架构师训练营」第 2 周作业 - 总结

森林

江帅帅:精通 Spring Boot 系列 03

古月木易

Spring Boot

程序员买买买,纸书半价,电子书55折,抢券叠加使用更划算

图灵社区

图灵教育 热门活动

GPU容器虚拟化:用户态和内核态的技术和实践详解

GPU容器虚拟化:用户态和内核态的技术和实践详解

Facebook:MVC不适合大规模应用,改用Flux_Facebook_Abel Avram_InfoQ精选文章