敏捷之道 (下)

开发过程中每天付出一点小的努力,避免代码「腐烂」。优雅的代码第一眼看上去,就知道它的用处,而且很简洁。

敏捷之道

<高效程序员的 45 个习惯> 读书笔记

任何一个愚者都能够让事情变得越来越笨重,越来越复杂,越来越极端,需要旁观者的指点以及极大的勇气,才能得到豁然开朗的局面。

新项目刚开始,代码很容易理解和上手,随着开发过程的推进,项目不知不觉演变成一个庞然怪物。

是为什么让它最终变得难以掌控? 开发人员在完成任务时,可能会难挡诱惑为节省时间而走「捷径」。这些「捷径」往往只会推迟问题的爆发时间,而不是把它彻底解决掉。

最简单的解决方式,就是开发过程中每天付出一点小的努力,避免代码「腐烂」。

代码要清晰地表达意图

代码阅读的次数要远远超过编写的次数,所以在编写的时候值得花点功夫让它读起来更加简单。

例如:

  • 默认参数或可选参数会影响代码可读性,使其难以理解和调试,最好明确地指明参数。
  • 改动代码以修复 bug 或添加新功能时,应有条不紊,先理解代码做了什么,如何做的。

看看代码例子

1
coffeeShop.PlaceOrder(2)

这个大概可以理解是在咖啡店下了订单,2 是什么意思呢?

不仿添加一些注释。

1
coffeeShop.PlaceOrder(2) // 2: large cup

有时候,注释是为了帮写的不好的代码补漏,不仿考虑用枚举值来表达概念。

1
2
3
4
5
6
7
const (
	Small = iota
  Medium 
  Large
)

coffeeShop.PlaceOrder(Large)

这段代码就很明白,是要一个大杯的咖啡。

作为一个优雅的开发者,应该时长提醒自己是否有版本啊让写出的代码更容易理解。

1
result := val << 1

如果你擅长位运算,就会明白只是把 val 的值乘以 2。但对于没有类似背景的人来说,他们能明白吗? 对于团队中的新人,可能会挠头不已,抓耳挠腮,百思不得「琪姐」。

1
result := val*2

用位移做乘法是在堆代码进行不必要且危险的性能优化,直接乘法看起来更清晰,不要表现得好像很聪明似的。

有意图的编程并不是意味着创建更多的类和类型,这不是进行过分抽象的理由。

增量式编程

开车进行长图旅行时,两手把我方向盘,固定在一个位置,两眼直盯前方,油门一踩到底几个小时,这样可能吗?

如果不对自己编写的代码进行测试,并且保证没有问题,就不要连续长时间进行编程。

相反,应该采用增量式的编程方式,增量式编程可以精简并结构化你的代码。所开发的代码基于即使的反馈,这些反馈来自小步幅方式编写代码和测试的过程。

采取增量式编程和测试,会倾向于创建更小的方法和更具内聚性的类,在编写代码时,要经常留心可以改进的微小方面,这可能会改善代码的可读性。将长函数拆分成短函数,使其变得更易于测试。

中庸之道

  • 如果构建和测试循环花费的时间过长,你就不会希望经常运行它们了。要保证测试可以快速运行。
  • 在编译和测试运行中,停下来想一想,并暂时远离代码细节,这是保证不会偏离正确方向的好方法。
  • 要休息的话,就要好好休息,休息时远离键盘
  • 要像重构业务代码那样,重构测试,而且要经常重构测试

保持简单

也许你看到一篇文章,其中提到了一个设计想法,放下文章,眼前的代码似乎马上就可以用到这样的模式。

你真的需要用它吗?

是不是特定的问题强迫你使用这个解决方案 ? 不要让过度设计,也不要将代码过度复杂化。

开发人员更应该为自己能够创建出一套简单并可用的设计而骄傲。

简单不是简陋! 相比一个过度复杂,拙劣的解决方案,简单的方案 通常更难以获得。

优雅的代码第一眼看上去,就知道它的用处,而且很简洁。这样的解决方案不是那么容易想出来的。优雅是易于理解和辨识的。

中庸之道

  • 代码几乎总是可以进一步精炼,但到了某个点之后,再作改进就不会带来任何实质性的好处了。
  • 简单,可读性高的代码。强行让代码变得优雅与过早优化类似,同样会产生恶劣的影响。
  • 简单的解决方案必须满足功能需求,为了简单而在功能上妥协,就是过度简化。
  • 一个人认为简单的东西,可能对另一个人意味着复杂。
  • 开发可以工作,最简单的解决方案。除非有不可辩驳的原因,否则不要乱用设计模式,高难度技术之类的东西,造成一大锅黏糊糊,乱七八糟。

编写高内聚,低耦合的代码

内聚程序高,表明各个成员共同完成了一个功能特性或是一组功能特性。

假定把所有衣服都扔到一个衣柜,当需要找一双袜子时,得翻遍里面所有的衣服。

如果每个页面包含展示逻辑,业务逻辑和访问数据的代码,臃肿的堆积在一起,如果要对数据库的表结构进行一次微调,这个微小的变化会导致应用中所有的页面发生变化。

假设有这样一个类,实现了 5 种完全不相干的功能,当 5 个功能的需求或细节发生了变化,这个类也必须跟着改变。如果一个类变化得过于频繁,这样的改变会对整个系统产生涟漪效应,导致更多的维护和成本。推书「敏捷软件开发: 原则,模式与实战」。

中庸之道

  • 一些东西拆分成很多微小的部分,可能会失去使用价值,当你需要袜子的时候,一盒毛线是不够用的。

告知,而非询问

有个「送报男孩和钱包的故事」,男孩将报纸送到你的门前,要求付报酬,你转过身让男孩从你的后屁股兜掏出钱包,并且从中拿到两美元,再把钱包放回去。

当男孩拿到钱包的时候,他拿走的数额不是你能控制的。送报男孩作为调用者,应该告诉客户需要付多少钱,男孩不能探寻客户的财务状况,也不能代替做任何决策。

告知,不要询问是一个很有用的技术,将功能和方法分为「命令」和「查询」两类,一个常规的命令可能会改变对象的状态,一个查询仅仅提供状态,不提供修改。

敏捷调试

即使是运作得最好的敏捷项目,也会发生错误。bug,错误,缺陷—不管被称作什么,它们总会发生。

要想更加有效地重用你的知识和努力,记录问题解决日志是很有用的。

不要在同一处跌倒两次,可以选择符合需求的任何格式,如下:

  • 问题发生日期
  • 问题简述
  • 解决方案详细描述
  • 引用文章或网址
  • 任何代码片段,设置或对话框截屏
  • 助记标签

1
2
3
2023/02/15
golang 更新 1.20 golangci-lint 在终端提示了很多错误
 github  golangci-lint 搜索相关 issus发现 brew/vscode-go 发行的 golangci-lint 都是旧版 1.50.1而此工具已更新至 1.51 修复了相关问题直接下载替换即可

如果面临的问题无法在日志中找到解决方案,在问题解决之后,要记得马上更新细节记录到日志中。

解决方案日志应该作为思考的一个来源,可以在其中发现某些特定问题的细节,对于某些类似但是有差异的问题,也能从中获得修复的指引。

中庸之道

  • 记录问题的时间不能超过在解决问题上花费的事情,要保持轻量级和简单,不必达到对外发布式的质量
  • 找到以前的解决方法非常关键,使用足够的关键字,以帮助查找
  • 如果通过 web 搜索,发现没人曾经遇到同样的问题,也许是搜索的方式有问题
  • 要记录发生问题时应用程序,应用框架或平台的特定版本
  • 记录团队做出重要决策的原因,否则 6-9 个月之后,想再重新回顾决策过程,这些细节就很难再记得,容易发生互相指责的情形。

对问题各个击破

单元测试带来的积极效应之一,就是它会强迫形成代码的分层,要保证代码可测试,就必须把它从周边代码中解脱出来,如果代码依赖其它模块,就应该使用 mock 对象。

识别复杂问题的第一步,是将他们分离出来。不可能在半空中试图修复飞机引擎,将其取出来放在工作台上之后更容易修复。

中庸之道

  • 将代码中其运行环境中分离后,问题消失不见了,有助于隔离问题,相反也有助于隔离问题
  • 以二分查找的方式定位问题很有用,将问题空间分成两半,看哪一半包含问题,再将包含问题的进行二分,并不断重复这个过程,直到发现问题本质。
  • 在处理问题之前,先查找问题解决日志。

报告所有的异常

编程,不仅要考虑正常状态下如何运作,更要考虑异常情况下会发生什么。

有些开发人员会采用临时的做法,捕捉到异常后,为了不看到编译器的提示,就把异常忽略掉。

必须处理或向上传播所有的异常,不要将它们压制不管,就算是临时做也不行。

中庸之道

  • 不是所有的问题都应该抛出异常。
  • 报告的异常应该在代码的上下文中有实际意义。
  • 如果代码中会记录运行时调试日志,当捕获或是抛出异常时,都要记录日志信息,这样做对以后的跟踪工作很有帮助。
  • 检查异常处理起来很麻烦,没人愿意调用抛出 31 种不同检查异常的方法。这是设计上的问题。
  • 要传播不能处理的异常。

提供有用的错误信息

发生错误时,显示通用的信息告诉用户发生了问题,要好过于系统崩溃造成应用执行错误的动作。然而类似「出错了」这样的消息,无法帮助团队针对问题做出诊断。

用户在给支持团队打电话报告问题时,我们希望他们提供足够多且好的信息,以帮助尽快识别问题所在。

  1. 记录日志
  2. 客户端展示包装的错误,将错误细节隐藏在「详情」按钮中,点击按钮可以将错误细节以邮件发给技术支持,或直接展示错误。
  3. 日志中记录的信息可能应该包含当时的系统状态,版本等快照

区分错误类型:

  • 程序缺陷: 这是真正的 bug,用户或技术支持对此束手无策,只能研发处理。
  • 环境问题: 如果能提供足够详细的错误,技术支持可以解决。
  • 用户错误: 由用户的输入造成的问题,用户可以重试。通过追踪记录报告的错误类型,可以为受众提供更佳合适的建议,为研发提供程序优化等。

中庸之道

  • 像无法找到文件这样的错误,本身而言无助于问题的解决。 「无法找到 /home/app/main.yaml 文件 」这样的信息更有效。
  • 在提供更多信息的同时,不要泄露安全信息,个人隐私,商业机密。
  • 提供给用户的信息可以包含一个主键,以便于在日志文件或是审核记录中定位相关内容。

敏捷协作

高效的协作是敏捷开发的基石。

团队中一个人的知识,经常可以解决另外一名成员的问题。只要允许大家自己想办法,就可以帮助团队不断成长。

  • 准备好再共享代码
  • code review
  • 不断完成旧任务,领取新任务,及时通报进展与问题

定时安排会面时间,要保证会议议题不会发散,每个人都应该只回答 3 个问题,如果要详细讨论某些问题,可以在会议结束后,再专门召集相关人员私聊。

  • 昨天有什么收获?
  • 今天计划做哪些工作?
  • 面临哪些障碍?

成为指导者

好的想法不会因为被许多人了解而削弱,好主意就像火,可以引领这个世界。

与别人共事,激励他们变得更出色,同时可以提升团队的整体实力。

成为指导者,并不意味着要手把手教成员怎么做,也不是在白板前讲座。多数时候,成为指导者,是指在帮助团队成员提升水平的同时也提高自己。

成为指导者意味着要分享,而不是固守。

中庸之道

  • 如果总是被一些懒于自己寻找答案的人打扰…
  • 为团队成员在寻求帮助之前,设定一个陷入时间,1 小时应该不错

做 code review

代码刚刚完成时,是寻找问题的最佳时机。

中庸之道

  • 不进行思考的 code review 没有任何价值
  • 代码复杂需要积极评估代码的设计和清晰程序,带着问题去复查

走向敏捷

一灯能除千年暗,一智能灭万年愚。 —- 慧能,中国禅宗第六代祖师

image-20230216173903886

本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy