惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyberwarzone
Cyberwarzone
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
A
About on SuperTechFans
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
腾讯CDC
S
SegmentFault 最新的问题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Hacker News
The Hacker News
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
B
Blog
IT之家
IT之家
Spread Privacy
Spread Privacy
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cisco Blogs
Recent Announcements
Recent Announcements
H
Hacker News: Front Page
AI
AI
I
InfoQ
H
Heimdal Security Blog
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
W
WeLiveSecurity
SecWiki News
SecWiki News
MongoDB | Blog
MongoDB | Blog
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
O
OpenAI News
阮一峰的网络日志
阮一峰的网络日志
T
Troy Hunt's Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
雷峰网
雷峰网
T
Tor Project blog
有赞技术团队
有赞技术团队
Schneier on Security
Schneier on Security
Last Week in AI
Last Week in AI

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考 Logstash+ElasticSearch+Kibana处理nginx访问日志
聊聊框架
2024-06-08 · via Posts on WKLKEN THINKING

很久没写了,感觉是要提高下更新频率了。

今天聊聊框架,线索是我的工作经历。

刚毕业那会

大学的时候,因为学的是软件工程,所以高级编程语言当时教的是 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。

有哪些需要注意的?

尽量避免手搓轮子!尽量避免手搓轮子!尽量避免手搓轮子!(强调三遍,受过太多苦)

大部份通用的功能,框架或开源的实现中都有,应该先看框架中本身是否自带,如果没有,寻求第三方库,如果还没有,再考虑自己实现。

尽量避免:

  1. 框架一般已经做到极简,堆业务逻辑出现一些代码上的重复是正常的,不要为了少写几行代码,在框架之上又封装了一层,相当于在约定之上,又做了一层自定义约定(其他维护者会骂娘的,没有共识,而是在框架的认知负担之上,又要学习这一层约定,复杂度太高,百害无一利)– 写代码的人爽了,维护代码的人非常不爽(要是一个人的项目,当我没说)
  2. 不要炫技。写一个 DSL 和平铺几个实现,我更倾向于后者。
  3. 不要一开始就上可扩展性,大量的抽象加一两个具体实现。

记住,可维护性更重要。

框架该怎么用?

像 Django 和 DRF 这类框架非常强大,不同人可以写出不同风格的代码,例如我们最早的 FBV 和 CBV,使用 DRF 可以继承 N 种 View/Viewset 实现。

但是这样的代码是不利于多人协作维护的。

应该形成项目内,或者组内的统一规范(这种规范静态代码检查大部份是扫不出来的)。

例如:

  • 纯 Django 项目应该使用 CBV,禁止用 FBV
  • 使用 DRF 时,禁止直接继承 *ViewSet,只允许继承 *APIView
  • SLZ 只允许到 View,禁止下传,禁止在其他模块用到

相当于,需要去学习框架,了解框架,用起来,知道各种用法/风格的优缺点,然后,在组织内形成共识,并落地为规范,这个规范新人在接触项目的第一天就能看到,新人看到的代码不会出现意外的惊喜。

那么,代码是不是太无趣了?

这时候写代码,是不是有点无聊?

因为框架限制了你,或者内部的规范限制了你?

是的,可能或者大概率会有点无聊,但是,上面的选择,是多人协作下比较稳的一种选择,或者说效率比较高的选择。

你是否经历过,google 一个小众框架报错只有几条结果甚至没有结果,然后花几天时间一点点 debug 解决(很有成就感是吧?);实现一个通用需求别的框架只需要一行配置而你用的这个需要自己手搓两天(可能搓出来也很有成就感是吧?);接手一个项目发现里面有七八种用法,甚至没有分层,在各个地方访问数据库(骂娘);接手一个项目发现用法跟标准框架不一样,而是多了一层封装,得去学习自定义的约定,问题是封装的不咋地老是得去擦屁股,然后查问题一查查一天(每天都来几个问题遇到过没?我遇到过)

自己写的爽,但是坑了未来的自己或者其他接手的开发,还是说,稍微不那么爽,效率高点少加班。

其实还是有一些有趣的。

你可以考虑分层,模块之间的依赖关系,数据的流转,做一些扩展,或者 dig 到更深的地方看看是怎么实现的。

其他

如果是 个人项目, 要用啥都行,手搓都行,开心就好。

如果是 一个人的项目,谨记客观选型不炫技,未来维护成本低,别人接手不骂。

如果是 多人协作的项目,复杂度越低越好,可维护性越高越好。