AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

最好的 Go 框架就是不用框架?

  • 2023-10-03
    北京
  • 本文字数:3090 字

    阅读完需:约 10 分钟

大小:1.58M时长:09:13
最好的Go框架就是不用框架?

 撰写本文时,我已经领导 Go 团队好多年了。我从初学者那里听到的最常见的问题是:我应该使用什么框架?

 

在使用 Go 的过程中最糟糕的事情之一就是遵循其它编程语言的方法。其它语言已经建立了“默认”框架:Java 的默认框架是 Spring,Python 的默认框架是 Django 和 Flask,Ruby 的默认框架是 Rails,C#的默认框架是 ASP.NET,Node 的默认框架是 Express,PHP 的默认框架是 Symfony 和 Laravel。而 Go 不同:没有默认框架。

 

更有趣的是,许多人建议你根本不应该(在 Go 中)使用框架。他们疯了吗?

 

Go 语言的哲学

 

Go 框架是存在的,但没有一个 Go 框架提供项其它语言框架那样的功能集。这点短期内不会改变。你可能认为这是因为 Go 生态系统比较“年轻”。但是还有一个更重要的因素。Go 是围绕 Unix 哲学构建的:

 

  • 一个程序只做一件事并把它做好。

  • 程序间协同工作。

  • 编写程序来处理文本流,因为这是一个通用接口。

 

这个理念来自 B 编程语言(C 语言的前身)的设计者肯·汤普森(Ken Thompson),他也是 Go 语言的设计者。

 

在实践中,Unix 哲学倾向于构建小而美的软件,而不是大而全的软件。你可以在你的终端中看到这些例子。例如:cat example.txt | sort | uniqcat 从文件中读取文本,sort 对行进行排序,uniq 删除重复行。所有命令都是独立的且只做一件事。这直接来自 Unix 哲学。得益于这样的设计,你可以独立开发比较小的自治命令。

 

在 Go 中,Unix 哲学在标准库中随处可见。最好的例子是应用最广泛的接口:io.Readerio.Writer 。最好的库都遵循这种哲学。

 

框架的设计违背这种哲学理念。通常,它们试图在一个框架内涵盖所有可能的用例。它们不是为了与其它工具一起使用而设计的,而且通常无法复用。这意味着不可能将开发成果转移到其它不兼容的框架。如果框架的采用率很低(或者就是死了),那所有的努力都白费了。

 

对你来说,什么是重要的

 

每个技术决策都有权衡,你的选择要对你和你的项目更有意义。

 

当你在从事一个短期项目(比如用时不到一周且用完即扔的概念验证项目)时,有些方案是有意义的。在这种情况下,最关键的因素是你能多快地完成它。但是如果你在从事一个持续很长时间的项目,并且你要与多人一起协作,那么这个决定的影响是巨大的。

 

对于大多数项目,最重要的参数是:

 

  • 你能以多快的速度启动项目

  • 从长远来看,你能以多快的速度开发项目

  • 对于未来的变化,项目的灵活度(这与前两点紧密相关)。

 

让我们开始评估我们的决定。

 

节省时间

 

框架最大的好处之一就是节省时间。运行一个命令就可以得到一个功能齐全的项目。框架通常提供一个固定结构的项目,而且如果你不知道如何做,它会有很大帮助。但与大多数其他技术决策一样,它不是没有代价的。

 

随着时间的推移,当项目增长时,你会很快触及框架在约定和限制方面的墙壁。框架作者的需求跟你的需求可能有所不同。框架创建者采取的决策可能适用于简单的 CRUD 应用程序,但无法处理更复杂的场景。如果继续使用,很容易就为了克服一个框架限制而迅速失去在项目启动上节省的所有时间。随着时间的推移,这可能会导致团队遇到很多挫折。

 

几年前,我在一家使用 Go 框架(我会略过框架名称)的初创公司工作。这家公司正在成长并创建新的服务。随着时间的推移,当我们想要支持的复杂用例越多时,我们就感到越痛苦。这个框架也是严重 Bugs 的来源。不幸的是,摆脱这个框架并不容易。

 

有一次,一些框架组件变得无法维护,与生态系统的其它部分不可兼容。我们被迫摆脱这个框架,而这个框架已经与整个系统紧密耦合。将其从数十个服务中移除是一个不小的任务,这需要一个跨团队的计划、需要多人数月的时间和努力,才能摆脱这个框架。即使这个项目最后成功了,我也不认为整个事情是成功的。如果有人更早做出不同的决定,所有花费的时间可以被利用得更好。整个项目都不是必要的。许多公司对开发团队缺乏信任也就并不令人奇怪了。

 

这是一个很好的例子,表明了一个小小的决定会在数年后变成一个代价高昂的需要“救援”的项目。

 


项目的可维护性

衡量项目的可维护性是一个有争议的话题——很难比较两个项目的可维护性。有些人说框架很棒,他们没有感到使用框架的痛苦。对其他人来说,框架可能是长期以来最大的噩梦。有些项目比其他项目更具挑战性,许多人认为与框架较劲只是工作的一部分。这就是为什么很难客观地衡量框架对项目可维护性的影响。

 

幸运的是,我们可以用一点科学知识来理解它。基于科学研究的《Accelerate: The Science of Lean Software and DevOps》一书,聚焦于找出表现最好和表现最差的团队的特点。对我们来说重要的是,良好性能的最重要的一个因素就是松耦合架构。

 

我领导的团队经常问我,“如何知道我们的架构是松耦合的”,最简单的方法之一是确保应用程序的部件可以轻易替换或删除。如果你的应用程序的部件很难删除,那么你的应用程序就是紧耦合的。这样的紧耦合会导致牵一发而动全身,引发多米诺效应。

 

为什么松耦合架构如此重要?需要承认,我们都是人,即使经过了最好的调研,我们也会犯错。当你选择了错误的库或框架,应该很容易替换而不需要重写整个项目。如果我们想要节省时间,我们应该考虑从长期来看有什么帮助,而不仅仅是在项目开始时。

 

请考虑一个场景,当你想要完全删除一个框架时,需要重写大量代码吗?它可以在多个服务上独立运行吗?如果不行,那么你需要花些精力将框架和核心逻辑分开。但是,这会牺牲框架一开始时带来的“省时”。

 

备选方案?构建服务时不用框架

 

你可能会觉得,在没有框架的情况下构建服务需要很长时间,尤其是如果你之前使用其它编程语言。我理解这一点,几年前当我开始用 Go 写程序时,我也有相同的感受。但是,不用框架并不意味着你自己需要构建一切东西,有许多经过验证的库会提供你需要的功能。

 

这意味着,你需要在调研上多花一点儿精力。如果你正在阅读本文,那你就已经在调研了!几个小时的调研时间在整个项目的生命周期中几乎不值一提。你这样做所带来的灵活性,很快会将你调研所花的时间“挣”回来。

 

如果你决定不使用框架,应该怎么办?一开始最大的障碍可能是如何构建一个服务。最简单的方法是一开始将所有东西放到一个文件中。你可以简单地开始,推迟一些决定,然后随着时间的推移演化你的项目。

 

如果有示例项目可以作为参考,那么这会很有帮助。你可以看看我在GoRemoteFest – github.com/roblaszczak/goremotefest-livecoding上的演讲“让我们用 Watermill 在 15 分钟内构建一个事件驱动应用程序”所用的项目。这个示例项目只需要两个外部库就可以运行了。

 

请随意 copy 这个代码库并根据你的需要调整,我确信这个示例不会有你项目所需的全部的库。我们发布了一篇文章介绍可以用来构建 Go 服务的 Go 库清单。这些库我们已经用了几年了,还解释了我们为什么使用这些库,以及如何识别类似的库是好还是坏。

 

文章链接:

https://threedots.tech/post/list-of-recommended-libraries/

 

当你的项目变得越来越复杂,而且你已经知道了你的库是如何协同工作的,那么你就可以开始重构它了。最后,你可能不需要那些看起来很关键的框架功能。得益于此,你可以得到一个更简单的项目并进行更少的调研。

 

总结

 

决定如何构建服务不是你应该走捷径的地方。从长远来看,做出错误的决定会对你的时间产生非常负面的影响。它会对团队的速度产生负面影响,更重要的是会影响士气。

 

在做出错误的决定后,你很快就会陷入沉没成本谬论的陷阱。与其成为解决自己制造的问题的英雄,我们应该避免制造这些问题。

 

作者介绍:

 

Robert LaszczakSlashID的首席工程师、三点实验室(Three Dots Labs)的联合创始人、Watermill库的创建者。

 

原文链接:

The Best Go framework: no framework?

2023-10-03 07:009605

评论 5 条评论

发布
用户头像
作者想表达的应该不是不用框架,而是别轻易用别人的框架,先做小而美的功能插件,最后整合成最适合公司业务的定制框架。 这样比直接用别人的框架,发现壁垒后再重构代价更小些。 当然自己整合一套扩展性,安全性,高效性都不错的框架也不是件容易的事,需要根据团队的时间和能力来考量。 所以这篇文章也只是根据作者自己情况的一个建议。
2023-11-16 23:09 · 广东
回复
用户头像
删了吧,你这个文章就是个笑话,框架的出现让企业级的应用喷涌而出,百花齐放,站在高出看问题,操作系统和应用程序完全不能类比,操作系统需要的是紧凑安全,富有扩展性生态,足够的灵活,大型应用需要的是规范,可扩展可和可维护性可靠性,至于性能都要往后稍一稍,流水的程序员铁打的项目,你说对了一半,编程和软件工程是个哲学问题,人们选择了它们就说明他们的必然性和正确性,存在即合理,不能张口就来,尝鲜是需要代价的,而且这个代价前人已经尝试过了,没必要写篇文章出来告诉我们封建专制的可持续发展性了优越性。
2023-11-02 13:52 · 上海
回复
用户头像
我们可以设计1w个小而美的组件,但是要有机、高效、安全的组合起来,还是离不开框架
2023-10-24 17:42 · 上海
回复
用户头像
设计框架是一个哲学问题,而不是技术问题。
2023-10-09 16:32 · 北京
回复
用户头像
项目做多了,之后把共用的部分提取出来还不是成了框架?如果框架不合适,何不自己从源码改造框架。如果没框架,每次做同样的服务,相同的层面不同的人有不同的做法,如何维护。
2023-10-04 16:46 · 广东
回复
没有更多了
发现更多内容

Hackathon | Mint Blockchain 启动全球 NIP 创意提案黑客松活动!

NFT Research

blockchain 黑客松 NFT\

助力 AI 技术共享,蚂蚁开源又一核心技术“因果学习系统 OpenASCE”

可信AI进展

人工智能 机器学习 开源

请重视你的简历

老张

面试 简历优化 简历

新特性速览!Sermant重磅更新,1.3.0 release版本发布

华为云开源

微服务治理 sermant 字节码增强框架

数据如何驱动AI大模型的竞争优势

百度开发者中心

人工智能 AI 大模型

简单聊聊数据库可以做什么,有什么用?

行云管家

数据库 云计算 大数据

亿级流量摩擦出来的 ES 稳定性之道

常清静

方法论 ES 建模 Elastic Search ES优化

AI时代我们的IT团队架构应该如何应变

Onegun

人工智能 AI 团队组织

精彩回顾 | 《国产数据库共话未来趋势》技术沙龙上海站成功举办!

阿里云数据库开源

数据库 阿里云 数据管理 国产数据库 polarDB

好用的鼠标键盘记录工具:Mouse And Keyboard Recorder激活中文

胖墩儿不胖y

Mac软件 鼠标管理工具 Mac软件鼠标辅助

小程序怎样成为平台““破壁人”?全网引流的3种姿势!

Geek_2305a8

数据资产入表“倒计时”,企业该如何抓住红利?

用友BIP

数据资产

身为程序员,你很有必要了解一下提效工具“JNPF”

互联网工科生

程序员 软件开发 低代码 JNPF

2024提升计划|优秀程序员的10大共性特征

SoFlu软件机器人

程序员 软件开发 代码 测试 单元测试 构架

揭秘加密货币周期:如何通过顶级代币指标洞察市场变化

Footprint Analytics

区块链 加密货币

探索跨语言、跨模态、跨任务的大模型驱动应用生态繁荣

百度开发者中心

人工智能 大模型

快手商品详情数据接口(ks.item_get)丨快手API接口

tbapi

快手商品详情数据接口 快手API接口 快手商品数据接口 快手数据采集

深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs

EquatorCoco

Docker 容器化 项目开发

软件测试开发/全日制/测试管理丨测试左移和测试右移

测试人

软件测试 测试开发

小程序能否成为移动应用实现动态更新与敏捷迭代的突破口?

Geek_2305a8

2023 CSIG青年科学家会议丨多模态大模型时代下的文档图像处理

热爱编程的小白白

软件测试/测试开发/岗位内推丨字节跳动岗位开放

测试人

软件测试

小度推出小度学习机K16:内容、AI功能、软硬件配置全面升级

新消费日报

探索大模型在端侧应用的新形态

百度开发者中心

人工智能 图像识别 大模型

Capture One Pro 22 for Mac(RAW图像处理软件) v15.4.2.12永久激活版

mac

苹果mac Windows软件 Capture One Pro 22 RAW文件转换器

通过小程序容器轻松打造自有App小程序生态

Geek_2305a8

【Spring技术专题】「实战开发系列」保姆级教你SpringBoot整合Mybatis框架实现多数据源的静态数据源和动态数据源配置落地

洛神灬殇

spring mybatis springboot 数据源切换 2024年第六篇文章

服务器里面打开浏览器访问不了会是什么原因

德迅云安全杨德俊

最好的Go框架就是不用框架?_编程语言_Robert Laszczak_InfoQ精选文章