十二、这一切是如何结合在一起的

谷歌地图一经推出就大受欢迎,它仍然非常重要,但它引入的新功能几乎什么都不是。谷歌对其地图网站所做的贡献是利用以前只有陡峭的学习悬崖才能获得的东西,并赋予它们简单的商标。这是相当多的。

关于 ReactJS 可能也有类似的说法。脸书没有人发明函数式反应编程。在脸书,似乎没有人大幅扩展函数式反应式编程。但 ReactJS 明显降低了准入门槛。以前,关于函数式反应式编程,在经验丰富的 C++程序员中有重复的评论;他们说:“我想我只是很愚蠢,或者至少,我没有计算数学博士学位。”有人可能会说精通 C++并不是一件容易的事;用 Python 让某样东西工作,不如用 C++让同样的东西工作,就像攀登当地公园的冬季雪橇山,不如攀登珠穆朗玛峰,是一种成就。此外,ReactJS 引入了足够多的变化,使得没有任何数学、计算或其他学位的合格 C++程序员有相当大的机会使用 ReactJS 并在其中发挥作用。也许它们不如对函数式编程特别感兴趣的纯 JavaScript 程序员有效。但是,学会有效地编程 C++是一个真正的“T2”成就,大多数优秀的 C++程序员都有相当大的机会用 ReactJS 有效地实现函数式反应式编程。然而,遵循维基百科上的计算机数学论文,用学术作者通常更喜欢的哈斯克尔语言实现一些东西,情况就不一样了。

在此结论中,我们将在本章中探讨以下主题:

  • 对所覆盖地形的回顾
  • 对产生神话人月的问题的免疫力
  • 反应只是一种观点——但这是多么好的观点啊!
  • 编程反应的乐趣
  • 网络之外的 ReactJS 开启了全新的前景。这里介绍的 ReactJS 作品,并不是 ReactJS 可能性的终结:只是开始

对覆盖地形的回顾

我们在这本书里已经从理论和实践上讲了很多。我们介绍了函数式编程、反应式编程和函数式反应式编程的基础知识。我们还介绍了一项技术,脸书反应堆。它使不一定精通计算数学的前端开发人员能够利用函数式反应式编程的一些优势(不幸的是,这是本文的一个显著特点)。这里的文字是为了跟随 ReactJS 的脚步,特别是为了让没有特殊数学背景的程序员理解。一路上,我们遇到了有趣的技术,如 Om、Brython 和 Jest,并了解了未来的前端网络开发可能会是什么样子。我们也许能够用自己选择的语言进行 web 开发,而不一定局限于 JavaScript。

我们还构建了两个系统,一个更小,一个更大,并试图演示如何解决问题的细微变化:有或没有 JSX,具有受控的表单元素值,以及通过经典表单 Hijaxing。关键不在于哪一种方法比另一种更好,因为这种需求需要不同的解决方案,我们希望增加至少一种方法在特定情况下有所帮助的机会。

一路走来,有理由说,正如关于 Python 所说的,“编程又有趣了!”每个系统都有它的怪癖,但不知何故,当用 ReactJS 旅行时,路上的减速带似乎更少了。这个标题对 CKeditor 的简单描述必然包含了一个减速带的解决方法,这个方法会让第一次使用 CKeditor 的用户感到沮丧。对于 ReactJS 代码中持续存在的问题的解决方法,几乎没有必要的警告。

神话中的人月可以避免吗?

弗雷德·布鲁克斯 1975 年的著作《神话中的人月》(40 多岁,当你读这本书的时候)是所有软件工程文献中被引用最多的著作《T2》。塔南鲍姆的经典教科书操作系统:设计和实现提到了布鲁克斯的头衔:

“OS/360 的设计者之一弗雷德·布鲁克斯(Fred Brooks)写了一本机智精辟的书(Brooks,1975),描述了他使用 OS/360 的经历。虽然不可能在这里总结这本书,但可以说,封面展示了一群被困在沥青坑里的史前野兽……”

在这里,有一个直接的相关性。为了解释原因,让我们对史蒂夫·卢舍介绍的“大咖”符号做一个变体。虽然在卢舍的头脑之外,也许没有人知道是什么激励他像他那样提出自己的观点,但卢舍显然熟悉运行时复杂性的经典大 0 符号,并且大概也熟悉它也被用来评估其他类型资源使用的复杂性的事实,例如内存。但我可能会建议,一个可能的额外灵感可能会有所帮助,正如大组织复杂性所解释的那样。如果“大咖”的复杂性在Could the Mythical Man-Month have been avoided?可以是噩梦般的和二次的——或者如卢舍尔所写的那样,Could the Mythical Man-Month have been avoided?——那么在一个单一项目中的通信复杂性中会出现一些令人怪异的熟悉的东西。

如果一个单片项目上有一个程序员,那么复杂度为零,因为没有必要避免踩其他程序员的脚。如果有两个程序员,沟通的复杂性恰恰是一个连接。如果有三个程序员,就有三个连接;如果我们扩展到 10 个程序员,文书工作将扩展到 45 个连接。IBM 对 OS/360 项目的做法是所谓的大蓝解决方案,它说:“既然我们有很多很多的工作要做,那就雇佣很多很多的程序员吧!”IBM 有超过 10 名程序员,因此有超过 45 个连接。

一个可能适合用来表示组织沟通复杂性的字符是互连的 HTML 丁巴特,可编码为☸☸:

Could the Mythical Man-Month have been avoided?

如果我们能够改造一个“大组织”的复杂性,即需要多少沟通来防止程序员破坏他人的工作,也许没有一个丁巴特或 emojicon 是完美的。但是我们可以说单片软件项目具有二次通信复杂性——对开发人员来说是Could the Mythical Man-Month have been avoided?,或者如果你愿意的话,是Could the Mythical Man-Month have been avoided?——以跟上其他变化并部分避免与其他开发人员的工作发生冲突。在操作系统/360 项目的规模上,这导致开发人员花了超过半天的时间只记录备忘录,以跟上其他程序员所做的事情。

有理由相信,如果操作系统/360 项目采用了像脸书用于 ReactJS plus Flux 的方法,那么可能就没有必要写《神秘人月》( T1)。

ReactJS 和 Flux 的组合是显式编写的,因此您不需要将手放在其他组件的口袋里。事实上,它是这样写的,如果每个人都在观察这种方法,你就不能把手放在其他组件的口袋里,除非你找到一种方法来破坏安全性。Could the Mythical Man-Month have been avoided?Could the Mythical Man-Month have been avoided?的通信复杂度不是二次的(就像在 OS/360 项目中一样);如果每个组件最多只有一个开发人员,那么通信方向的数量就要少得多,并且在Could the Mythical Man-Month have been avoided?可能几乎不会超过线性。其影响是巨大的。

虽然不清楚脸书是否足够坚持纯粹主义,以实现理论上可能的最佳结果,但似乎确实很明显,脸书——互联网上最大的组织之一,可能有相当于(或大于)操作系统/360 项目规模的前端开发人员——拥有比单片操作系统/360 努力更好的通信规模。也许脸书是许多更快地宣传自己的优势而不是劣势的组织之一。但是,我在网上的任何资源中都找不到任何迹象表明,脸书开发者之间的通信量已经失控,就像在操作系统/360 项目中一样,或者说,必要的内部通信量已经繁重到足以成为一个让开发者的生活真正变得更加困难的问题。

ReactJS 只是一个视图,但是多好的视图啊!

查尔斯·塞尚有句名言:“莫奈只是一只眼睛,但却是一只眼睛!”莫奈没有试图炫耀他的结构和解剖学知识,只是复制了他的眼睛所看到的。对他作品的一致判断是“只有一只眼睛”和“多好的眼睛!”事实上,莫奈的细节可能模糊不清,他反抗艺术,试图用解剖学的深刻知识和结构知识打动人,而这些知识远远超出了肉眼所能看到的。

ReactJS 是一个框架而不是库,这意味着您应该在 ReactJS 提供的结构内构建一个解决方案,而不是将 ReactJS 插入到您自己构建的解决方案中。一个库的典型例子是 jQuery,在这里你用自己的方式构建一个解决方案,并在 jQuery 适合你设计的结构时调用它。

然而,ReactJS 是一个视图。并不是说这一定是好是坏,但是 ReactJS 并不是一个完整的 web 开发框架,甚至没有成为你永远需要的唯一工具的内涵。它专注于成为一个视图,在脸书的产品中,这不包括任何形式的 AJAX 调用。这不是开发反应堆的重大疏忽;期望您使用 ReactJS 作为视图来提供用户界面功能,并根据需要使用其他工具来满足其他需求。本文还没有涉及将 reatjs 与您最喜欢的工具一起使用,但是如果您最喜欢的工具不会互相踩在对方的脚上,请将它们结合起来。ReactJS 可能会也可能不会与其他视图冲突,但它旨在与非视图技术一起工作。

编程又好玩了!

当网络第一次出现时,我有了我的第一个“编程又有趣了!”体验。我已经对用 Unix 和 C 编程有所了解,当我被告知可以在网页中包含图像时,我预计了在类似 C 的环境中从头开始告诉如何显示图像所需的工作量。我含蓄地想,“我工作太多了。”但是我非常惊讶地发现,一个图像只需要<IMG SRC=Portrait.GIF>就可以包含在网页中,图像本身不需要嵌入到网页中;它同样可以优雅地作为<A HREF=Portrait.GIF>Click here!</A>提供。就这样,我开始第一次接触一种声明性而非命令性的语言。也许这不是严格的编程;当然,在 JavaScript 之前,它不是图灵近似。然而,它让我可以轻松地用电脑做我梦寐以求的事情。

几年后,我有了我的第二个“编程又有趣了!”体验后有朋友建议我试试 Python。当时,我是一个语言收藏家;我唯一想知道但不知道的语言是 Icon、C++和一些汇编语言。对于语言收集者来说,一个普遍的现实是,他们的第一个新语言项目比任何进一步的工作都要慢、更难、更令人沮丧。之后会变得更好,但对于第一个项目来说,“它总是比你想象的要长,即使你考虑到它总是比你想象的要长。”然而,对于 Python,我的惊喜是,“什么?已经开始工作了吗这只是冰山一角。

我的故事是成为一名语言收藏家,找到 Python,然后停止学习新语言的努力,这在 Python 爱好者中并不是一个特别不寻常的故事。埃里克·雷蒙德当然在他的文章《为什么是 Python》中找到了一些更深层次的注释。在 http://www.linuxjournal.com/article/3882。蟒蛇是一个魔法王国,街道是用胶水铺成的,受益的不仅仅是大师。

之前没有提到的是,如果你把鼠标悬停在http://xkcd.com/353/的卡通形象上,会出现这样的信息:我昨天用 Python 写了 20 个短程序。太棒了。佩尔,我要离开你了...现在 Perl 也是一种很好的语言,一度是我的最爱,但是 Python 还是有一些东西的。

最后,我最后的也是最伟大的“编程又有趣了!”我开始欣赏 ReactJS 的时刻到来了。ReactJS 提供了 XHTML 5 和 HTML5 所没有的东西,在创建像标签一样可以使用的有用组件方面。

不管 XHTML 中的“X”代表什么,它并不意味着“在主流使用中,人们会构建和部署许多有趣的新标签。”HTML5 提供了许多新的组件,比如<input type="date" />,但它们并没有得到普遍的支持,这不是 IE 必须成为派对生活的另一种情况。主流和当前的非微软浏览器对 HTML5 备受关注时大声而清晰地宣布的功能的覆盖范围非常不一致。有多种方法可用,集成 HTML5 之前存在的多种 JavaScript 日期选择器中的一种在今天可能和它们是新的时候一样有意义。虽然像http://html5please.com/这样的网站值得称赞和使用,但它也是一个主要问题的征兆。

ReactJS 和 JSX 在这些失败的地方取得了成功。本文没有介绍如何创建一个<DatePicker />函数,但是一旦创建了这个函数,你就可以像创建本地 HTML 标签一样轻松地将其包含在你的 JSX 中。如果怀旧的人在 HTML5 画布上绘制分形,并制作可滚动和可缩放的<LogisticMap /><VonKochSnowflake /><MandelbrotSet /><SierpinskiGasket />,这些可以像简单的旧标签<img />一样轻松地包含在 JSX。ReactJS 中定义的组件在很大程度上不同于手动配置和连接 JavaScript 日期选择器来处理您的表单。它们就像经典结构化编程中的子例程,在某种意义上说,只要重用有意义,它们就可以很容易地被重用,并被组合成更大的构建块。

类型

有人可能会说,生产有用组件库可以赚钱,这些组件几乎可以用来扩展对其他 web 开发人员开放的基本有用标签集。

此外,如果我可以借用罗宾·马丁的《杀死 Smalltalk 的东西会杀死 Ruby》中的并使用稍微礼貌一点的语言,那么代码评审中的关键指标(除其他外)就是评审者不得不问“他们在想什么”的次数对于“他们在想什么?”度量,被检查代码的可接受分数是 0。任何高于这个的都是不可接受的。此外,这个度量标准与代码评审无关。

在 Python 中,这样的时刻很少:它们确实存在,就像搜索“Python 可变默认参数”会显示的那样,但是它们很重要,因为它们很少。这不同于“他们在想什么?”JavaScript 中的参数,例如“可以使用变量而不声明它们(但如果这样做,它们将是全局的)”和“可以编写伪经典构造函数(但如果在调用它们时忘记使用 new 关键字,它们将在全局命名空间中痛击事物。)“JavaScript 中的环境是这样的,一个关键的语言倡导者,比如道格拉斯·克洛克福特,尖锐地警告人们避开大量的基本语言,而且随着时间的推移,似乎变得越来越挑剔。

最终,似乎 ReactJS 和 Python 是心有灵犀。从本质上来说,两者都很小很简单。也许两者都有缺陷,但是缺陷在哪里“他们在想什么?”时刻是例外,不是常态。正如 ReactJS 宣布时一条讽刺性的推文所说,“脸书:重新思考既定的最佳实践。”ESR 提到了 Python 奇怪地选择了大量空格的问题。

“和大多数黑客一样,意识到这个事实后,我本能地厌恶地退缩了。

早在 20 世纪 70 年代,我还没到用 Fortran 批量编程几个月的年龄。如今,大多数黑客都不是,但不知何故,我们的文化似乎保留了一个相当准确的民间记忆,那就是那些老式的固定字段语言有多讨厌。事实上,当时用来描述帕斯卡和 C 语言中面向标记语法的新风格的术语“自由格式”几乎已经被遗忘了。几十年来,所有的语言都是这样设计的,或者几乎所有的语言都是这样设计的;不管怎样?看到 Python 的这个特性,很难责怪任何人最初的反应,好像他们意外地踩到了一堆冒着热气的恐龙粪便。”

ReactJS 也有勇气说,那些创建 CSS 的人可以创建非常简单的 JavaScript,而不是只在故意功能不足的模板语言中工作。现在,JavaScript 被选为一种特定领域的语言,以故意留下所需的力量。但是设计师没有必要召唤 JavaScript 的全部力量。他们可以创建 99%的简单 JavaScript,而这在功能不足的模板语言中是可以做到的,JavaScript 开发人员可以创建其余 1%的功能强大的 JavaScript,因为在功能不足的模板语言中解决这个问题是有问题的。

总结

在这一章中,我们看了一个比细节稍高的层次。其他章节详细介绍了几个项目,但在这里我们看了 ReactJS 代表的一些主要胜利,以及计算中一些最著名的问题。

这本书旨在用脸书的 ReactJS 涵盖函数反应式编程的理论和实践。这几乎不是涵盖函数式编程、反应式编程或函数式反应式编程的第一个标题,但它可能是不具备博士级数学能力的函数式反应式编程治疗中的早期标题。其中一部分是通过使文本有点哲理性来实现的。从某种意义上说,这是为了让一些资深程序员理解而仅仅是挑战而付出的代价,但对于大多数资深程序员来说,理解并不是不可能的。JavaScript 和 ReactJS 中最好的函数式反应式编程是基于函数式编程的熟练程度,Haskell 中最好的函数式反应式编程也是基于函数式编程的熟练程度;那里没有真正的区别。然而,一个不同的事实是,一个典型的经验丰富的 C++程序员有很大的机会熟练使用 ReactJS。脸书在让人们更容易接触到事物方面做了相当令人印象深刻的工作。

JavaScript 是一种通用的语言,如果你在用 Scheme 的方式思考时接近它,你可以获得大量的生产力(当然!)或 Python 方式,或 C#、Erlang、Perl、Ruby、Java、Haskell、PHP、Lisp 或 Visual Basic。也许没有其他编程语言的思维方式能够达到纯函数驱动的 JavaScript 思维的上层,但是你可以用 JavaScript 说很多东西,而不需要是一个母语人士,带着完美的 JavaScript 口音!

这些在 ReactJS 中都没有丢失。也许最后一盎司的力量不能从函数式反应式编程中挤出来,除非你在一些非常具体的数学领域有非常高的熟练程度,但是 ReactJS 已经显著降低了函数式反应式编程的好处的进入壁垒。函数式反应式编程过去在门上有一个不成文的标志,上面写着“数学编程运动员专用。”现在不是了。与 ReactJS 一起工作可能是一个纯粹的优势,但是所有提到的其他专业都可以从 ReactJS 中获得很多东西,而不需要知道除了通常嵌入在计算机科学和信息技术中的重要熟练程度之外的许多数学知识。

有人说过,开发者很少为买单;他们为章节付费。这本书旨在作为一个整体来工作,不同的部分说明了对其他部分的补充方法,这样每个部分都增加了整体。但它也认真地打算为那些想要将自己定位于某件事情的人提供作为独立资产的完美工作的章节。

接下来的步骤从这里开始

有无数的方向可以探索。可以深入挖掘,探索 ReactJS 的核心。您还可以探索将 ReactJS 集成到使用其他技术来解决其他问题的项目中。

然后,您可以从 Lisp 或 Python 编程 ReactJS。(这不仅仅是因为只有当你来自“Lispy”或“Pythonic”背景时,你才能用 JavaScript 中的 ReactJS 编程。您可以使用 ReactJS 创建动画网页,而无需离开 Lisp 或 Python 编写一行 JavaScript 代码。)

您可以创建比 HTML5 的任何版本都更丰富的组件集,并像 HTML 1.0 提供的组件一样轻松地使用它们。

也许最令人兴奋的可能性是,ReactJS 不再只适用于 HTML/Web。它现在提供了一个杀手级的应用“学一次,写在任何地方。”现在你出色的 JavaScript 技能和学习函数式编程的努力,比网络解锁了更多。举例来说,为 iOS 编写代码同样容易。现在看到首页在https://facebook.github.io/react-native/。这本书让你不仅能在网上使用 ReactJS,还能快速、良好地学习 ReactJS Native,这意义深远。

你已经爬到了跳水板的顶端。现在是时候加入进来,尽可能地引起轰动了。

关于使用函数式反应式编程和 ReactJS 的最佳方法,最好的说法可能是根本不要使用 ReactJS。是用 ReactJS 玩,就像你玩新鲜的雪一样。格拉斯哥哈斯克尔编译器的说法完全适用于反应堆:忘记它是你工作中使用的东西。玩它,就像你小时候得到一个巨大的乐高玩具一样。看看你能造什么,不能造什么。

*编程又是新的;有仙尘。就像程序员曾经获得了使用程序员贡献的子程序和内置函数的能力一样,现在前端网络开发人员已经获得了使用开发人员制造的组件的能力,就像在他们的 JSX 中包含一个IMG标签一样简单。我们需要去http://html5please.com/了解到<input type="date">有一个琥珀色的警告标签,提示“小心(甚至是)有 polyfill”,这样的日子已经一去不复返了。你需要——更糟糕的是手动地——在每一页上用你的表单连接一个 JavaScript 日期选择器的日子也一去不复返了,你可能会用 58 行重复的导致压力伤害的代码在一页上获得一个日期选择器。一旦有人做了一个合适的 ReactJS <DatePicker />函数,问题就解决了,只需要包含不到一行代码,你可以在一个页面上包含它零次、一次或多次。“甚至。什么时候?正在部署。和。垫片。“对互联网爆炸者 8”是故意使用标点符号,特里·普拉切特在巨魔的演讲中也使用了标点符号,而且是强调性的。至于“互联网爆炸者”这个术语,这个名称已经存在很长时间了,开发者,或者至少是我,在实现一个可以与任何普通浏览器一起工作的解决方案时遇到了两个问题,然后再次让事情运转起来,这一次是浏览器,嗯,聚会的生活。

维基百科以中立的“观点”为目标,毫不犹豫地写下了早期版本:

这一版本的 Internet Explorer 因其安全问题和缺乏对现代网络标准的支持而受到广泛批评,经常出现在“有史以来最糟糕的技术产品”名单中,PC World 将其称为“地球上最不安全的软件。”[2]这甚至没有开始提到所有的小精灵灰尘,这意味着你不必管理The next steps from here过渡,因为你在概念上炸毁了一切,并在特定的时间点重建事物。

有一个充满可能性的世界可以探索,也许有一件事可以说:

这本书开始的时候,作者的家是 Python。当这本书结束时,作者的家是 ReactJS。*