MVC 死了,接下来会发生什么?
2024-04-27 14:20:46

MVC 死了,接下来会发生什么?

在本系列的死生开始部分 ,我们将看到像 React.js 这样的接下 UI 框架是如何引入一种替代方法,来取代使用 MVC 作为设计 Web 应用程序和 UI 的死生主要方法的。请继续阅读 ,接下了解更多信息。死生

Js  、接下 Elm 、死生 Cycle.js 和其他 UI 框架引入了一种构建用户界面的接下新方法 。从函数式反应型编程到用户界面开发 ,死生它们甚至改变了我们对用户界面的接下看法。这些方法很快就打破了 MVC 及其兄弟(MVP、死生 MVVM 等)看似不可避免的接下统治地位。本文是死生系列文章的第一篇 ,将简要介绍这种构建 UI 的接下新方法 ,并列出它与传统方法相比的死生一些优点 。这些因素是如此强大 ,以至于在我看来,我们现在很有可能正在见证 MVC 时代的终结。

功能性反应用户界面开发的概念

从表面上看 ,像 React.js 这样带有 Redux 架构 、 Elm 和 Cycle.js 的框架似乎完全不同。Redux 应用程序最初看起来类似于普通的 JavaScript 应用程序 ,可能主要关注函数式编程。Elm 应用程序有自己的语言,而 Cycle.js 应用程序只由反应流组成  ,这些反应流以惊人的方式结合在一起 。

但是在表面之下,所有这些框架都有一个共同点: 功能性反应式 UI 开发的本质。


上面的图片大致概述了这些概念 ,它们在几乎所有培养响应式编程的现代用户界面框架之间共享 。首先要注意的是 ,所有的事情——所有的变化  、事件和更新——都朝着一个方向流动,形成一个循环 。这篇文章将给出一个简短的周期解释 ,而后面的文章将进入更多的细节 。

函数式反应式 UI 开发

这个循环由四个数据结构(State、 Virtual DOM 、 Event 和 Action)和四个组件(View ()-Function、 DOM-Driver 、 ActionCreator 和 Updater)组成 。DOM-Driver 由框架提供,而其他组件必须由应用程序开发人员实现。

假设我们的应用程序 todo-list 已经运行了一段时间,用户按下按钮在 todo-list 中创建一个新条目 。这将导致 DOM 中的按钮单击事件 ,DOM-Driver 捕获该事件并将其转发给我们的 ActionCreators 之一 。

ActionCreator 获取 DOM 事件并将其映射到操作。操作是命令模式的一个实现,也就是说,它们描述了应该做什么 ,但是它们本身不修改任何东西 。在我们的示例中,我们创建一个 AddToDoItemAction 并将其传递给 Updater 。

Updater 包含应用程序逻辑 。它保持对应用程序当前状态的引用 。每次它从 ActionCreators 之一接收到一个操作时,都会生成新的状态。在我们的示例中 ,如果当前状态包含三个 todo-item 并且我们收到 AddToDoItemAction ,Updater 将创建一个新状态,其中包含现有 todo-item 和一个新状态。


状态被传递给 View ()-Function ,它创建所谓的 VirtualDOM 。顾名思义 ,Virtual DOM 并不是真正的 DOM ,而是一种描述 DOM 应该是什么样子的数据结构 。上面的代码片段显示了一个简单的 < div > 的 Virtual DOM 示例。稍后的文章将详细解释 VirtualDOM 及其优点 。

VirtualDOM 被传递给 DOM-Driver ,后者将更新 DOM 并等待下一个用户输入。有了这个,这个循环就结束了。

好处

功能性反应式 UI 开发相对于传统方法有三个主要的优势 ,它们都是巨大的优势: 直接的测试、全面的事件流和时间旅行(是的,真的)。

简单的测试

View ()-Function 和 ActionCreators 是简单的映射 ,而 Updater 对它接收到的 Actions 执行折叠(通常也称为 reduce)。

所有组件都是纯函数,纯函数非常容易测试 。


纯函数的结果只取决于输入参数,它们没有任何副作用。要测试一个纯函数 ,只需创建输入参数 、运行“测试中的函数”并比较结果即可 。没有样机,没有依赖注入,没有复杂的设置 ,没有其他技术是必要的 ,没有乐趣的测试 。

综合事件流

响应式编程有很多乐趣——除非它不是 。图形用户界面的控制流本质上是基于事件的。应用程序必须对来自用户或服务器的按钮单击、键盘输入和其他事件作出反应。应用反应技术 ,无论是观察者模式、数据绑定还是反应流  ,都是自然而然的。

不幸的是 ,这些技术都是有代价的。如果组件 A 调用组件 B ,则很容易在 IDE 或调试器中查看连接 。但是 ,如果两个组件通过事件连接起来 ,那么这种关系就不那么明显了 。应用程序变得越大,就越难理解其内部结构。

功能性反应应用程序的体系结构通过定义所有组件都必须遵循的简单事件流来避免这些问题。


无论应用程序的规模有多大 ,事件流永远不会改变。

时间旅行

功能性反应式应用程序允许您在时间上来回旅行——至少在应用程序的上下文中是如此 。如果我们存储初始状态和所有操作,我们可以使用一种称为“事件采购”的技术。通过重播操作,我们可以重新计算应用程序所处的每个状态。如果我们只重播最后的 n-1,n-2 ,n-3... 动作 ,我们实际上可以回到过去  。通过修改记录的行动流 ,同时应用它们 ,我们甚至可以改变过去。正如您可以想象的那样 ,这在开发和修复错误时非常方便。


第一个时间旅行调试器已经建立 ,但我认为我们才刚刚开始了解的可能性,更惊人的工具将在未来发布 。

摘要

到目前为止 ,我们只触及了功能性反应式 UI 开发的表面,但是到目前为止 ,应该很清楚这种方法具有一些巨大的优势 。以后的文章将更深入地讨论技术细节 ,但也会展示其缺点(或者我们称之为“尚未解决的挑战”)  ,并展示如何将所学到的经验教训应用于 JavaFX 应用程序的示例。



(作者:新闻中心)