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

推荐订阅源

P
Privacy International News Feed
Martin Fowler
Martin Fowler
D
Docker
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
U
Unit 42
T
Tailwind CSS Blog
J
Java Code Geeks
G
Google Developers Blog
MongoDB | Blog
MongoDB | Blog
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
美团技术团队
F
Fortinet All Blogs
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recorded Future
Recorded Future
N
Netflix TechBlog - Medium
Google DeepMind News
Google DeepMind News
Hacker News: Ask HN
Hacker News: Ask HN
L
LINUX DO - 最新话题
Microsoft Security Blog
Microsoft Security Blog
N
News and Events Feed by Topic
I
Intezer
TaoSecurity Blog
TaoSecurity Blog
NISL@THU
NISL@THU
小众软件
小众软件
博客园 - 聂微东
博客园 - Franky
有赞技术团队
有赞技术团队
P
Palo Alto Networks Blog
爱范儿
爱范儿
H
Hacker News: Front Page
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
P
Proofpoint News Feed
I
InfoQ
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
H
Heimdal Security Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
量子位

咸糖 - 自律者自由

2025 年终总结:降噪、重构与长期主义 在新加坡和新山吃过最好的食物(持续更新) 写给还在迷茫的你:我的三本大学回忆 2024 年终总结 Neovim: No Crash Incremental Selection 2022 年终总结 使用 neovim 作为 PDE(个性化开发环境) shell 是一个不错的生产力工具 使用二八法则省力地学习 awk 肉身翻墙新加坡安顿指南 使用 Docker Compose 建立你自己的开发环境 我为什么使用双向链接做笔记? 关于焦虑和拖延症 Golang: 如何处理日渐膨胀的 interface 使用番茄工作法来更好的利用你的时间 Unix 如何杀死一个进程和它的子孙进程? Golang: 让你的零值更有用 使用 Mock 和 Interface 进行 Golang 单测 关于 Golang Slice 的一些细节 总结一些计算机常用的原则 重新学习英语语法 上班族近期小半年入门投资基金组合的学习与实践经历 疫情期间的肉身翻墙新加坡指南 About me 软技能:大厂底层员工打工指南 软技能:我是如何获取知识与信息的? 分布式的令牌桶算法的实现 实现一个AtomicInteger GC root 在哪里? 什么是 Minor GC/Major GC 漏桶算法的设计与实现 剑指offer 单例模式 TCP 针对面试学习 Actor 如何处理阻塞消息 Akka 源码解析 How to learn scala AES 需要限制 SEED 长度 Java 如何区分==与.equals()方法 2018年年度总结 Java 集合扩容
关于编写可维护的代码的一些实践与想法
xiantang · 2022-04-10 · via 咸糖 - 自律者自由

文章目录

【注意】最后更新于 December 29, 2025,文中内容可能已过时,请谨慎使用。

关于编写可维护的代码的一些实践与想法

最近在改一个代码风格迥异并且经历过很多手的历史代码,发现中间中了很多代码设计上的一些反模式的错误。导致我修改代码以及新增功能的时候变得非常的困难,这篇文章是在带着个人情绪的情况下写出的,可能会存在一些主观性。

我下面列举几点我认为十分影响维护性的编码行为。

重复编写相同逻辑

冗长的相同逻辑,编写两遍。很多时候部分开发遇到一段性能较差的历史代码,但是又缺乏时间去优化这段代码,于是我们会重新写一套具有相同行为的代码,同时开出 API 接口出来用。虽然这样做的确是完成了既有的任务,但是其实是非常有隐患的。

如果有一个新来的同事需要修改既有 API 的行为,会狠狠的踩坑,因为两套逻辑同时在线上跑,并且具有相同的行为,很有可能这个新同事可能只改了一套逻辑,而且忽略了另外一套逻辑,这种情况真的很容易存在,因为新人往往是缺乏信息的。在 QA 不够充分的情况下,会引入难以排查的 BUG。

不要上来就直接加 if else 的特殊逻辑

很多时候,我们遇到一些需求,简单一看其实没什么修改的,只需要在主流程或者抽象中加入一句 if else 这样的特殊逻辑。 这样的简单的判断逻辑有很大可能在不久的将来,例如两三个月后狠狠的给你一拳。 在考虑加 if else 前,思考下这样写对之后自己的修改方便嘛?能否写在配置文件中用配置中心修改? 实在要加就需要给这段代码加上注释。需要确定你自己的代码的行为,而不是堆一堆逻辑上去,别人问到行为的时候说可能会做这个?可能会做那个? 通过巧合的方式编程,只会带来越来越多问题。

延迟抽象

程序员真的是一个非常有意思的群体,对 抽象 这件事情特别的钟情,包括我也是。我在各种仓库也见过好的抽象和烂的抽象。比较烂的抽象往往是那种,在一个接口 interface 中暴露出 10+ 个函数出来,同时每个函数的真正实现就只有两三行,这个我们一般叫它 宽接口。它的缺点是当你横向拓展的时候需要实现 10+ 个函数,非常痛苦,灵活性非常的差。同时每个实现的函数很有可能都是空实现,里面都没有实际执行的代码。

我的建议是:

  1. 先去写一些实现类,先简单用 switch 语句等行为控制调用,然后慢慢的根据实现类的共性慢慢地抽象出上层的接口,如果你用 Go 可以看看我之前对 Golang 抽象的一些思考。Golang: 如何处理日渐膨胀的 interface
  2. 将接口的函数数目大大减少,每个接口最多 4 个函数,这样实现起来较为方便,将大接口根据 单一职责原则 将功能拆分成不同的接口, 然后组合成不同的大接口。可以参考 Golang 的 https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/io/io.go;l=127 的实现。

写代码少炫技

一行代码写出来一遍,但是会被人读百遍,所以写的时候简单性很重要,秀的代码/滥用设计模式的代码难以维护,同时会给系统带来复杂度。

将代码 group 起来

我经常发现一些代码,整个函数有 500+ 行,同时没有任何注释,并且整个函数 70% 都是在一个 for loop 里面做的。 我的建议就是如果你在写代码之前将这个函数要做的事情拆成一个个较小的事情,然后每个事情前面都会有注释,代码的可读性会好很多很多。

结语

吐槽结束,希望自己能在写代码的时候多思考一些,写出方便修改的代码。

文章作者 xiantang

上次更新 2025-12-29 (4c152d04)

赞赏支持

微信打赏 支付宝打赏