发布于 2026-01-06 3 阅读
0

回归 MVC 的本质

回归 MVC 的本质

这是我前几天听的一期Go time节目的后续报道,那期节目似乎激发了我的创作灵感。

它讲解了用 Go 语言进行 Web 开发,其中一些内容让我印象深刻。

生成 HTML 的一个警示故事

节目一开始就提到内置模板库表达能力不足,并介绍了 Go Buffalo 框架使用了Plush 库。

Plush 功能强大、灵活且可扩展,旨在让您编写模板变得更加轻松。

进入翡翠

大约八年前,我参与了一个用 Scala 编写的大型项目。我们决定使用 Jade 模板引擎来生成 HTML,它和 Plush 一样,允许你在模板中进行许多巧妙的代码编写。

起初感觉很棒,但很快就变成了一场噩梦。Jade 的灵活性让我们搞得一团糟。随着越来越多的业务逻辑渗入模板,我们的模板变得丑陋、难以理解且难以测试。

在软件开发中,我常常把灵活性看作是团队可以用来自缚的绳子,我倾向于更喜欢非常有主见和约束性的东西(比如 Go!)。

我们学到了什么?

软件工程师注定要不断重新学习。我们已经忘记了关注点分离,尤其是模型-视图-控制器(MVC)设计模式所规定的指导原则。

MVC

人们对MVC的误解之深令人惊讶。如果你去Reddit或Twitter看看,你会听到有人告诉其他开发者“MVC不适合Go语言”。

人们常常认为MVC架构只关乎文件夹结构、类名或其他一些相当肤浅的细节。因此,当一些来自Rails等框架的开发者展示他们用Go语言编写的、包含文件夹数组的代码时,他们往往会遭到嘲笑和排斥。

MVC 并没有规定文件夹结构,我担心很多人似乎没有理解这个原则的要点。

模型-视图-控制器(通常称为 MVC)是一种架构模式,常用于开发用户界面,它将应用程序分为三个相互关联的部分。

控制器

拦截“请求”(例如 HTTP 请求),解析它们,然后调用相应的“模型”,获取结果数据,并将其发送到“视图”。在 Go 语言中,这通常是一个http.Handler

模型

简单来说,它存放着你的领域逻辑。我个人觉得这个名字起得不太好,但关键在于关注点分离。它必须与控制器和视图解耦,所以如果你看到任何与 HTTP 相关的数据从控制器传递过来,很可能就违反了这种解耦原则。此外,它们也不应该了解视图的任何信息。

看法

它对控制器或模型一无所知。它应该接收某种类型的参数,ViewModel该参数仅仅是渲染视图所需的数据集合。一个设计良好的视图应该简洁明了,不包含领域逻辑;因为模板很难进行低成本的测试。

这些原则能给你带来什么?

您的域名代码与系统的其余部分完全分离,因此易于测试,并且可以“插入”到您的 Web 服务器以外的不同用途;例如 CLI 工具,或者作为软件包供其他人使用。

创建和编辑视图非常简单,因为它们仅仅是将一组通用数据映射到 HTML(或其他格式)。这也使得前端开发人员等更容易访问它们。

您的控制器存在一些明显的缺陷,而且也很容易测试。

回到最初的问题,我会对那些允许我为视图编写极具表现力的代码的工具保持谨慎。这类工具会用便捷和强大的功能诱惑开发者,但除非你非常自律,否则往往会导致抽象层泄漏。

现在想想你可能读过的所有关于 HTTP 服务器和 Go 的教程。好的教程会推荐所有这些原则,即使它们可能只是被提及。与其让社区围绕 MVC 的概念兜圈子,不如直接接受它。这是一个经过实践检验的模式,而且大多数人都在提倡它,只是没有明确地表达出来。如果我们都明确地表达出来,也许就不会每周都有关于如何构建 HTTP 服务器的文章了!

如何构建你的 Web 应用程序

  1. 理解MVC的概念。
  2. 你的http.Handlers 就是你的控制器,确保它们只做控制器应该做的事情,如上所述。
  3. 你的其他所有业务逻辑(模型)都放在其他地方,以包的形式围绕实际功能展开。如果是银行,我可能会创建诸如银行、银行服务等相关的包AccountCurrencyCustomer的控制器会调用这些包中的函数来执行有用的操作。
  4. 根据你构建的内容,你可以使用编码包输出 XML 或 JSON,如果是 HTML,则只需使用template/html.
文章来源:https://dev.to/quii/go-back-to-basics-with-mvc-4p6m