作为Go 语言的团队领导者这几年时间,我从初学者那里听到的最常见问题是“我应该使用什么框架?”。我的想法是使用过去的语言经验去编写 Go 程序往往会让结果变得非常糟糕。

其他的编程语言已经建立了 “默认” 的框架。Java有Spring,Python有Django和Flask,Ruby有Rails,C#有ASP.NET,Node有Express,PHP有Symfony和Laravel。但 Go 没有默认框架,这一点跟其他编程语言完全不同。

并且,很多过来人建议你根本不应该使用框架。到底该怎么办?

从库构建 Go 服务可能会给人一种构建弗兰肯斯坦的怪物的感觉。

Go 语言哲学

Go 语言有很多框架,但没有一个提供像其他语言框架那样的功能集。

这种情况短时间内还会持续。

你可能认为这是因为 Go 语言的生态更年轻。但更重要的是,Go 是围绕 Unix 哲学构建的,Unix 的哲学要求编写的程序需要具备以下三要素:

  • 只做一件事,并做好。

  • 程序间协同工作。

  • 处理文本流,因为这是一个通用接口。

这种哲学起源于 B 编程语言(C 语言的前身)的设计者 Ken Thompson, 并以同样的哲学思想在 2006 年创建了 Go 语言。

将 Unix 哲学运用实践中,你会编写出多个独立的软件来做好每一件事,而不是写出一个巨大的程序去做所有事情。这些例子在 Linux 终端中就能经常看到。比如:cat example.txt | sort | uniq。cat从文件中读取文本,sort对行进行排序,并uniq删除重复项。所有命令都是独立的,只做一件事。它源自 Unix 哲学。由于这样的设计,你可以独立开发更小的、自主的命令。

在 Go 中,Unix 哲学在标准库中随处可见。最常见的就是最广泛使用的接口:io.Reader和io.Writer。最好的库也遵循这一理念。

框架的设计往往是 “反 Unix 哲学而行”。语言框架试图在一个框架内涵盖所有可能的用例。它们不是为与其他工具一起使用而设计的,而且通常不能重复使用。这意味着不可能将开发工作转移到其他不兼容的框架。如果一个框架没有人用,那么针对该框架所有的所有努力都会白费。

对你来说,什么才是真正重要的

每个技术决策都有代价。你需要选择项目可以承受的代价, 并从决策中获得尽量大的收益。

当你在做一个项目的简单技术验证 (Proof of Concept)时,最重要的是你可以多快的完成。但如果这是个持续时间长,涉及多人协作的大型项目时,这个技术验证带来的代价将会是巨大的。

对于大多数项目,最需要关注的是以下几点:

  • 启动项目的速度

  • 完成项目的速度

  • 项目适应外来需求变化的能力, 这和上一点息息相关

让我们来逐条分析下影响我们决策的因素。

节省时间

语言框架给出的最大承诺之一是节省时间。只需一个命令,就能启动一个可用的项目。语言框架通常提供项目的默认架构,这会对入门有点帮助。但与大多数其他技术决策一样,它也有一定的代价。

随着时间的推移,当项目增长时,你会很快碰到该语言框架的约定和限制。语言框架的需求大概率会跟你的项目有区别。语言框架提供的教学文档可能适用于简单的 CRUD 应用程序,但一般无法处理更复杂的场景。 为了和语言框架的限制作斗争,很容易就会将启动项目所节省的时间全部浪费。长期以往,这会给团队带来很多挫败感。

几年前,我在一家使用某个 Go 语言框架起家的公司工作。公司正在发展并且不断的创造新的服务。随着时间的推移,当我们想要支持更复杂的用例时,我们开始越发痛苦。不仅如此,长此以往,使用语言框架逐渐成为了产生严重 Bug 的主要原因。但摆脱语言框架远不如想象中容易。

有一次,一些框架组件变得无人维护并且与生态的其余部分不兼容。我们将不得不去掉它。但是, 该框架中的所有组件之间耦合非常高。从几十个服务中删除一个组件非常困难。这需要多团队协作,并大概率会带来一些事故。即使最后我们成功删除了这个组件,我也不会觉得这是件值得骄傲的事。如果有人早点做出不同的决定,我们就可以更好的利用为了删除这个组件所花掉的时间。这也是为什么很多公司对开发团队不太信任的主要原因。

为几年前的小决定付出了高昂的代价, 这个故事是个很好的例子。

项目的可维护性

量化项目的可维护性一直以来都是个有争议的话题——很难比较两个项目哪个可维护性更高。一些人觉得使用语言框架很好, 使用很方便。但是对于一些复杂的项目,长期使用语言框架会使开发工作变得越来越困难。并且,还有很多人觉得跟语言框架作斗争是他们的正常工作。因此很难客观地衡量框架对项目可维护性的影响。

但是,我们可以通过一些手段真正理解它。基于《加速:精益软件科学和 DevOps》一书。这本书重点描述了如何找出表现最好和最差的团队的特点。书中提到,想要让一个团队表现更好,最重要因素之一是让项目架构的耦合更加松散。

我领导的团队成员经常问我如何知道我们的架构是否松散耦合。这里有一个好方法,如果你应用里的组件可以被轻松替换或删除, 说明这个应用是松散耦合的。但是, 如果大多数组件都很难被替换,改动一个组件会导致其他地方发生问题的情况,则说明你的应用耦合很高。

为什么松耦合架构如此重要?首先我们需要承认,我们是人, 即使做了最周密的准备,我们仍然可能犯错误。当你选择了错误的框架或库时,应该很容易替换它而不用重写整个项目。如果我们想节省时间,我们应该从长远来看某些决策是否有收益,而不仅仅是在项目开始时。

考虑一个场景,当你想要完全删除框架时。它需要重写大量代码么?它可以独立地在多个服务上完成吗?如果没有,你可以努力将框架与核心逻辑分开。但当你这样做时,使用框架被节省的时间就已经开始被浪费了。

替代方案?在没有框架的情况下构建服务

你可能觉得如果不用语言框架的话,构建服务会花费很长时间。特别是当你从其他语言转型到 Go 语言时。我懂你的痛。几年前,当我开始用 Go 语言编程时,我也有过同样的感觉。这是一种毫无理由的的恐惧。不使用语言框架不代表你需要自己编写所有代码。有许多经过验证的库可以提供你需要的功能。

你需要花更多时间做调研,寻找更好的答案。比如找到并阅读本文。在整个项目的生命周期中,几个小时的调研不算什么。足够的正确信息带来的灵活性将让你很快让项目回到正轨。

如果你决定不使用框架,你应该怎么做?开头最大的障碍可能是如何构建服务。最简单的方法是开始时只用一个文件编写所有逻辑。一切从简,推迟一些决策,随着时间的推移改进你的项目。

拥有可用作参考的示例项目会很有帮助。你可以查看我在 GoRemoteFest 上使用 Watermill 演示在 15 分钟内构建事件驱动应用程序时使用的项目 – github.com/roblaszczak/goremotefest-livecoding。这个例子只需要两个外部库就可以正常运行。

随意克隆这个 Git 并测试。为了帮助你处理更具体的用例,下周我们将发布一篇文章,其中包含可用于构建你的 Go 服务的 Go 库列表。我们已经使用它们几年了。我们还将解释为什么我们使用这些库,以及如何知道一个外部库是否值得使用。

在不终止项目的前提下修改项目的某些部分是很实用的。

当你的项目变得更加复杂,并且你已经知道你的库如何协同工作时,你可以开始重构它。你可能不需要很多看起来很重要的框架功能。长此以往,你得到一个更简单的项目,并最终花了更少的时间去调研。

如果你正在寻找一些复杂项目的最佳实践,你应该查看 Wild Workouts - 我们们功能齐全的示例 Go 项目。我们发布了一本描述我们如何构建应用程序的书。

总结

当一个项目开始时,决定如何构建服务是最不应该走捷径的地方。从长远来看,错误的决定会对团队的效率产生负面影响,还会影响士气。

在做出错误的决策后,你很快就会陷入沉没成本谬误陷阱。我们不应该成为解决他们制造的问题的英雄,而应避免制造他们。

读完此文,你应该了解了使用语言框架的代价并了解如何做出权衡。你现在可以做出负责任的决定。我希望这篇文章至少能帮助一家公司避免需要经历跨团队经历几个月才能完成的的重构项目的痛苦。

你是否有任何关于使用语言框架的恐怖故事?评论里见!

原文地址:

https://threedots.tech/post/best-go-framework/

原文作者:

Robert Laszczak

本文永久链接:

https://github.com/gocn/translator/blob/master/2022/w49_Best_Go_Framework.md

译者:鱼雷

校对:iddunk

往期推荐

「每周译Go」如何在Go中构造 For 循环

《Google Go编程规范》终于搞定了!

2023年Kubernetes最佳实践

想要了解Go更多内容,欢迎扫描下方

最好的 Go 框架:没有框架?相关推荐

  1. 新浪微博应用 IE下面框架嵌套框架的问题解决

    新浪微博应用 IE下面框架嵌套框架的问题分为两种: 1.回调的参数有误: 2.session丢失: 第一个问题,需要亲们仔细研读接口文档, App.AuthDialog.show({client_id ...

  2. 模板方法(设计一个稳定的父类框架,框架中的有一些步骤是可变的,将可变的步骤子类中来实现)

    模板方法设计模式的意图 设计一个框架,框架中整体步骤不可变,但是其中的有一些步骤是可变的,将可变的步骤放在不同的业务或者不同的模块对应的子类中来实现 举例 我们平时玩手机,我们可以将玩手机的过程分成以 ...

  3. DL框架之AutoKeras框架:深度学习框架AutoKeras框架的简介、特点、安装、使用方法详细攻略

    DL框架之AutoKeras框架:深度学习框架AutoKeras框架的简介.特点.安装.使用方法详细攻略 Paper:<Efficient Neural Architecture Search ...

  4. DL框架之Keras:深度学习框架Keras框架的简介、安装(Python库)、相关概念、Keras模型使用、使用方法之详细攻略

    DL框架之Keras:深度学习框架Keras框架的简介.安装(Python库).相关概念.Keras模型使用.使用方法之详细攻略 目录 Keras的简介 1.Keras的特点 2.Keras四大特性 ...

  5. 技术帖:砖混、砖木、钢混、板楼、塔楼、框架、框架剪力墙等概念之区别优劣...

    技术帖:砖混.砖木.钢混.板楼.塔楼.框架.框架剪力墙等概念之区别优劣 http://bbs.fdc.com.cn/showtopic-16331376.aspx天天听KFS说这些词,资料上写这些词, ...

  6. 小白自学Java框架,框架的全面解析总结

    springmvc工作机制(原理) DispatcherServlet主要用作职责调度工作,本身主要用于控制流程 1.springmvc将所有的请求都提交给DispatcherServlet,它会委托 ...

  7. spring框架mvc框架_Spring的MVC测试框架入门–第1部分

    spring框架mvc框架 最新推出的主要Spring框架是Spring MVC测试框架,Spring Guys声称它是"一流的JUnit支持,可通过流畅的API测试客户端和服务器端Spri ...

  8. spring框架mvc框架_Spring MVC测试框架入门–第2部分

    spring框架mvc框架 这个迷你系列的第一个博客介绍了Spring MVC测试框架,并演示了其在单元测试Spring MVC Controller类中作为控制器而不是POJO进行单元测试的用途. ...

  9. android http最新框架,Android框架学习笔记02AndroidAsycHttp框架

    上一篇中我们介绍了OkHttp3.0框架的基本使用方法,这一篇我们学习一下Android的另外一个网络请求框架--AsyncHttpClient框架.Asynchttpclient框架是一个开源的异步 ...

  10. 基于Tiles框架Struts框架的UI 设计—几种组织HTML和JSP视图组件

    摘要每个web应用开发者一定组织视图组件,例如  页首,正文体和页尾. 有许多技术可以组织这些组件, 但每个都有优缺点.这篇文章包括了7个可用的解决方案并让你了解 Tiles框架和Struts框架的灵 ...

最新文章

  1. C++实现输入两个整数n和m,从数列1,2,3...n中随意取几个数,使其和等于m,要求列出所有的组合
  2. python语音播报计算结果_Python 天气查询到实现语音播放
  3. mysql多实例(三种方法)
  4. 吴恩达深度学习笔记4-Course1-Week4【深层神经网络】
  5. 函数基本使用-函数的定义以及调用执行线路图
  6. Entity Framework Core 1.1 升级通告
  7. 自我价值感缺失的表现_不同类型的缺失价值观和应对方法
  8. Linux命令行下载文件百度云盘
  9. 19【14】DIEN:深度兴趣演化⽹络
  10. Response.End方法
  11. Firefox无法打开VMWare console的解决方案
  12. 基于微信校园跑腿小程序毕业设计设计与实现毕设参考
  13. 【3D目标检测】点云数据 To 360度全景图
  14. 1、【易混淆概念集】-前三章 1 工作绩效数据、信息、报告
  15. java计算机毕业设计html5健身房信息管理系统源码+mysql数据库+系统+lw文档+部署
  16. Windows系统自带磁盘读写测速工具
  17. JAVA 处理带AM 或 PM的时间
  18. php优势和技术应用
  19. 激活函数(sigmoid和ReLU)
  20. CTF--信息技术对抗赛ISCC之安卓逆向分析

热门文章

  1. 创龙基于TI Sitara处理器的EtherCAT主站开发案例
  2. css:去除滚动条样式(隐藏滚动条)
  3. uc保存html,uctxt 怎么一点就打开?另存为也没用
  4. 手机app测试分析方法 -- 逻辑分析法(数据测试方法)
  5. html绝对路径图片无法显示
  6. python语言中tup的意思_Python基础知识: 元组
  7. WINSERVER 2016 评估版转正式版及激活方法
  8. 项目管理 | 项目风险识别都有哪些方法?
  9. Java编写的 基于控制台的航班信息系统
  10. 爱情是一味的付出吗?