聊聊框架
很久没写了,感觉是要提高下更新频率了。
今天聊聊框架,线索是我的工作经历。
刚毕业那会
大学的时候,因为学的是软件工程,所以高级编程语言当时教的是 Java,当时所有教材都是英文版的大部头。
那时候选修课,学了 XML,学了设计模式,当然只是学,一知半解。
然后疯狂地用 Java 写东西,做项目,调试,学 Servlet/JSP(最近去了图书馆,发现2024了尽然还有JSP的新书,真是。。。。)所以毕业前,我一直认为自己未来会加入 Java 大军(想想那时候真的如日中天,想不到自己后来用的语言越来越小众)。
无脑学习 SSH,包括大四实习那会,只有我一个进入了 Java 组,当时花了很多时间折腾实习公司的自研框架,徒手搭建。
那时候对框架是无脑地崇拜,这里配配那里配配就 work 了,很神奇,但是如果一个 xml typo 就可能让你 debug 半天,这可能也是后来自己对框架的偏好会倾向于:不喜欢约定
过多的框架。
毕业了
我并没有如愿以偿加入 Java 大军,如果当时选了那条路,可能至今还在北漂。
后来面了阿里的 SDET,选择了杭州,然后南下了。
那时候工作,测试多余开发,常常加班,常常周末去公司,
工作的关系,接触了非常多的语言,Java/C++/Perl(现在应该很少人用了吧)/Python/Bash 等等,然后用 Python 实现了一些提升效率的测试工具。算是在繁忙的测试工作中寻找到一点开发的乐趣。
后来决定走,原因是因为想做回开发。算是遵从自己的内心吧。
那时候自己啃 Python 那本《Python 学习手册》,都快翻烂了。
然后网上投了简历,拿了个 Offer 之后,南下深圳。
第二份工作
测试转开发,并且是 Python 开发,准确来说是 Web 开发。
那时候对框架没啥概念,因为做测试工具的时候并没有机会接触太多,只懂一些皮毛。
那时候小组内重度使用 Tornado 以及 Flask。
目前 Tornado 应该很少人使用了吧?当时的感觉是写起来有点别扭,不过也还行。然后另一个就是 Flask。因为当时是 CS 架构,所以主要工作就是写 API。
对 Flask 也算情有独钟吧,轻量,简单直接,好用,产出效率杠杠的,是我喜欢的类型。
当时也自学了下 Django,第一印象,约定
有点多,有点重,额,不喜欢。
第三份工作
后来我司因为不可抗力,额,没了。
当时找工作,那时候是 2014 年左右,万众创业,满地的创业公司。根本没有找大厂,直接去了一家小创业公司,CEO 是国外回来的,用的 Python,后端开发加我一共三个。
那时候技术栈也是 Flask,原因是第一个招进来懂 Python 哥们(很厉害)的个人偏好。
做得还行吧,但是小公司管理后台的需求比较多,后来竟然需要一个专职开发做管理后台(Flask+Sqlalchemy+Flask-admin)。
第四份工作,至今
后来不到十个月,额,又没了。
Gap 了 100 天,找工作,面试进了大厂。
一二十个 Python 开发 的一个中心(现在应该翻了几倍),做 Django。
从抗拒 Django,理解 Django,到选择 Django,也算是经历了完整历程。
后来上 DRF,也是抗拒,还行(但是还谈不上喜欢)。
内部也形成了比较好的分层/规范等。
后来技术栈加入 Golang, 一开始 Gin + GORM(v1) 感觉有点香,但是后来主导两个大项目的选型,一个用的 Chi + Sqlx(网关),另一个用的 Gin + Sqlx(权限中心)。
但是实际使用很多第三方框架
,或者配合做一些开发,由于主导权不在自己手里,可以看到很多不是特别合理的配置。
例如:巨无霸开发框架(应该用 Core+Contrib 的模式更为合理),为了微服务而微服务的框架(加个字段加 N 层 N 个项目),手搓的 ORM,手搓的 XXX。
那么框架怎么选?
用不用框架?特别是做 Golang 的时候,直接用标准库,也不是不行。
如果是简单或者小项目,用什么其实无所谓。但是,如果是多人协作/需求复杂这类项目,用个框架显然能事半功倍。因为不用框架,可能很多很细碎的业务无关的功能,都需要手搓,然后慢慢慢慢,你的项目中的框架
其实跟社区的框架差不多。
框架对于生产力有一个非常大的提升,原因是,社区红利。一个好的框架,其生态非常完善,你遇到的 90% 以上的问题,都有现成的解法,即使没有现成的,也有可以参考的。
Go 当时的 Web 框架非常之多,各有特色,但是现在显然 Gin 胜出了。
Python 的同上,Django 目前应该算第一 (FastAPI 是后起之秀,用起来很强大,但是,我不喜欢约定
过多的框架)
原则就是:除非某个框架的 feature 特别适用于你的业务场景 (或者排第一的框架不能满足某个硬性条件),否则选社区最流行的,这样能少踩很多坑。
并且,不要因为协作开发中某个人特别熟悉某个相对小众的框架而选择它,最好还是客观评估。有时候宁愿选择大家都不怎么熟悉但是简单的,而不是某个人精通的(你擦几次这种项目的屁股就知道有多难受了)。
选择框架的标准,我觉得应该是:一个初级开发没有接触过,能在一周内通过阅读文档,搭建环境,写 Demo 的方式熟悉大体的框架,并且能在第二周开始修简单的 bug。
有哪些需要注意的?
尽量避免手搓轮子!尽量避免手搓轮子!尽量避免手搓轮子!(强调三遍,受过太多苦)
大部份通用的功能,框架或开源的实现中都有,应该先看框架中本身是否自带,如果没有,寻求第三方库,如果还没有,再考虑自己实现。
尽量避免:
- 框架一般已经做到极简,堆业务逻辑出现一些代码上的重复是正常的,不要为了少写几行代码,在框架之上又封装了一层,相当于在约定之上,又做了一层自定义约定(其他维护者会骂娘的,没有
共识
,而是在框架的认知负担之上,又要学习这一层约定
,复杂度太高,百害无一利)– 写代码的人爽了,维护代码的人非常不爽(要是一个人的项目,当我没说) - 不要炫技。写一个 DSL 和平铺几个实现,我更倾向于后者。
- 不要一开始就上可扩展性,大量的抽象加一两个具体实现。
记住,可维护性更重要。
框架该怎么用?
像 Django 和 DRF 这类框架非常强大,不同人可以写出不同风格的代码,例如我们最早的 FBV 和 CBV,使用 DRF 可以继承 N 种 View/Viewset 实现。
但是这样的代码是不利于多人协作维护的。
应该形成项目内,或者组内的统一规范(这种规范静态代码检查大部份是扫不出来的)。
例如:
- 纯 Django 项目应该使用 CBV,禁止用 FBV
- 使用 DRF 时,禁止直接继承
*ViewSet
,只允许继承*APIView
- SLZ 只允许到 View,禁止下传,禁止在其他模块用到
相当于,需要去学习框架,了解框架,用起来,知道各种用法/风格的优缺点,然后,在组织内形成共识
,并落地为规范,这个规范新人在接触项目的第一天就能看到,新人看到的代码不会出现意外的惊喜。
那么,代码是不是太无趣了?
这时候写代码,是不是有点无聊?
因为框架限制了你,或者内部的规范限制了你?
是的,可能或者大概率会有点无聊,但是,上面的选择,是多人协作下比较稳的一种选择,或者说效率比较高的选择。
你是否经历过,google 一个小众框架报错只有几条结果甚至没有结果,然后花几天时间一点点 debug 解决(很有成就感是吧?);实现一个通用需求别的框架只需要一行配置而你用的这个需要自己手搓两天(可能搓出来也很有成就感是吧?);接手一个项目发现里面有七八种用法,甚至没有分层,在各个地方访问数据库(骂娘);接手一个项目发现用法跟标准框架不一样,而是多了一层封装,得去学习自定义的约定,问题是封装的不咋地老是得去擦屁股,然后查问题一查查一天(每天都来几个问题遇到过没?我遇到过)
自己写的爽,但是坑了未来的自己或者其他接手的开发,还是说,稍微不那么爽,效率高点少加班。
其实还是有一些有趣的。
你可以考虑分层,模块之间的依赖关系,数据的流转,做一些扩展,或者 dig 到更深的地方看看是怎么实现的。
其他
如果是 个人项目, 要用啥都行,手搓都行,开心就好。
如果是 一个人的项目,谨记客观选型不炫技,未来维护成本低,别人接手不骂。
如果是 多人协作的项目,复杂度越低越好,可维护性越高越好。