Skip to content
This page has been auto-translated and may contain errors.View in English

什么是框架?

docs.scrimba.com

假设你正在构建一个小型网络应用:账户、信息流、设置页面。在你自己的想法出现在屏幕上之前,你需要将 URL 转换为页面的代码、与数据库通信的代码、保护密码安全的代码,以及当某些内容改变时重新绘制屏幕的代码。这些都不是你的应用的核心想法。每个应用都需要它,而且大多数内容在项目之间基本相同。

你可以自己编写所有这些基础设施代码,人们确实这样做过,多年来都是这样。这很慢,微妙的 bug 就隐藏在其中,每个团队最终都会得到一个略有不同、略有破损的相同机制版本。框架是积累的答案:共享的基础设施代码,经过一次编写并由数千个项目强化,以告诉你自己代码放在哪里的结构打包。你构建使项目成为你自己的部分;框架处理每个项目重复的部分。

框架不是网络专属的东西。它们存在于构建程序的任何地方,本章讨论的是这个想法本身,适用于任何语言和任何领域。

什么是框架(和什么是库)

这个词使用得很宽泛,所以这里是真正重要的区别,在代码中:

js
// 库:你的代码负责,在需要时调用库。
const label = dateLibrary.format(order.createdAt, "MMM D");

// 框架:框架负责,调用你插入的代码。
export default function OrdersPage() {
  return listOfOrders();
}

第一行是你在掌控:你的程序运行,它为一项工作借用工具。第二行则不同。你永远不会自己调用 OrdersPage。你编写它,将其放在框架期望的位置,框架在正确的时刻调用它,这里,当访客打开订单页面时。

这个转变有一个名字:控制反转。对于库,你的代码控制程序的流程并借用辅助工具。对于框架,框架控制流程,你的代码填充它为你留下的空白。一个有用的简化说法:你调用库;框架调用你。

同样的形状出现在编程的每个角落。Django 接收网络请求并调用你的视图函数。Flutter 运行应用并询问你的小部件要绘制什么。Unity 运行游戏循环并每一帧调用你的脚本。pytest 找到你的测试函数并为你运行它们。不同的领域,一个想法:框架拥有引擎,你提供它被设计来容纳的部分。

如果图片有帮助的话:库就像一个工具箱放在你身边,当工具有用时你就伸手进去。框架更像一栋建筑的框架,当你到达时已经站立。墙壁、电气和管道有其位置,你的工作进入使建筑成为你自己的房间。两者都为你节省了努力;区别在于谁决定了建筑的形状。

结构伴随期望而来,这是一个特点。大多数框架实践**约定优于配置**:将文件放在框架期望的位置,以框架期望的方式命名,一切都会自动连接,无需设置代码。Rails 使这个短语出名,大多数现代框架都遵循某个版本。回报是任何了解框架的开发者都可以打开任何在其上构建的项目并知道在哪里查看。代价是约定是你在任何工作之前需要学习的另一件事,与其对抗几乎总是比遵循它更痛苦。

控制反转改变了你阅读和调试程序的方式。在普通脚本中,调用栈从你的代码开始,其上的所有内容都是你的。在框架内,栈从框架内部深处开始,你的函数作为框架选择调用的条目出现:钩子、处理程序、生命周期方法。老笑话准确地描述了它:"别打电话给我们,我们会打给你。"实际上,这意味着学习框架不是关于其 API 表面,而更多关于其时序、它调用你的哪些函数、何时以及它期望什么回报。当行为让你惊讶时,答案通常存在于那个时序中,框架的生命周期文档是值得保持打开的地图。

Juno框架和库 库是一个工具箱:你的程序掌控全局,需要时拿起一个工具。框架更像一栋建筑的框架:结构已经竖起来,你在其中构建你的房间。让我恍然大悟的简化说法是你调用库,但框架调用你。
Juno框架和库 你调用库;框架调用你,这个转变叫做控制反转。框架与约定搭配:将代码放在框架期望的位置,它会自动连接。遵循约定而不是与之对抗,这是很好地使用框架的大部分技能。
Juno框架和库 控制反转意味着调用栈从框架开始,你的代码以它调用的钩子形式出现。所以真正要学的是时序:你的哪些函数被调用、何时调用,以及框架期望什么回报。调试框架应用是读取其生命周期,越早不再觉得这像魔法,就越好。

框架给你带来什么,花费什么

框架的案例是具体的。需要花费你数周时间的问题已经解决了,并由首先遇到硬边缘情况的人解决:密码处理、表单验证、路由、渲染。你的项目得到一个新队友可以在几分钟内认出的结构,因为它与该框架上的所有其他项目的结构相同。你继承了一个生态系统:插件、教程、回答的问题和已经熟悉其内容的人的招聘库。

成本同样具体,值得同样直视。框架是一个你无法控制的大型依赖,有自己的 bug、自己的步伐和自己的观点。在你的第一页呈现之前有一个学习曲线,你学到的一些是关于框架的知识而不是关于编程的。你的代码弯曲适应它的形状,这使得你停留越久就越难离开。框架会移动:主要版本到来,模式被重新考虑,保持更新是你在普通代码中没有的持续工作。

两个列表都不能单独赢得胜利。平衡完全取决于项目,所以对任何框架要问的问题是"这个框架是否让这个项目更简单"。框架通过让你的项目更简单来证明其价值。 当它这样做时,乐意使用它。当它没有时,接下来的两章是关于尽早认出这一点。

生态系统效应是加号中被低估的条目。在一个成熟的框架上,你的问题是新的概率接近于零:认证、文件上传、发送电子邮件、部署,有人已经为每一个打包或记录了文档。这将许多天的构建转换为数小时的组装。镜像的减号条目是这种流畅度是以框架命名的:你知道的一些是"Django 如何做到这一点"而不是"网络服务器如何工作"。注意每个便利下的总体想法,这就是这些文档的目的。

两个成本只在生产中显现。首先,抽象会泄露:框架的便利表面隐藏了真实的机制,在魔法行为不当的那一天,你最终会调试机制,现在通过一个你没写的额外层。要预算理解你的框架在底层做什么,因为最终你会需要它。其次,升级跑步机是一个真实的条目:大代码库的主要版本迁移可以占用数周,跳过它们悄悄地变成未修补的安全问题而不是。根据纯代码替代方案衡量两者,纯代码有更少的移动部分,没有东西要迁移,但为你重新打开每个解决的问题来再次解决,自己承担风险。这个权衡是选择和学习框架的主题。

Juno框架买和花费的东西 框架给你解决的问题、一个可认出的结构和整个帮助生态系统。作为交换,你接受一个大依赖、一个学习曲线和它做事的方式。两边都是真实的,所以要携带的问题是它是否让你的特定项目更简单。有时答案是一个开心的是,有时普通代码是更平静的路径!
Juno框架买和花费的东西 生态系统是交易中被低估的一半:在一个成熟的框架上,你遇到的几乎没有问题是新的。继续注意每个便利下的总体想法,否则你的知识变成"这个框架如何做到这一点"而不是事物如何工作。框架应该让项目更简单;这是整个测试。
Juno框架买和花费的东西 两个成本晚点账单给你:抽象会泄露,所以某天你通过一个你没写的层调试框架的机制,主要版本迁移是真实的工作,不能被永远跳过。提前为两者定价,与纯代码自己的重新解决问题框架已完成的价格相比。我已经支付了两张发票;都不有趣,都不是教条的原因。

接下来的内容

有了这个想法,自然的下一个问题是实际上那里有什么:框架的类型参观主要系列,从网络到游戏到测试,以及每个中最受欢迎的选项。之后,选择和学习框架变得实际关于选择一个、学习一个,以及知道何时根本不需要一个。如果上面的 JavaScript 例子感到陌生,JavaScript 轨道涵盖了语言本身,这是在任何在其上构建的框架之前的正确第一步。