生成式AI领域的最新成果都在这里!抢 QCon 展区门票 了解详情
写点什么

软件质量的黄金准则

  • 2020-08-13
  • 本文字数:2056 字

    阅读完需:约 7 分钟

软件质量的黄金准则

在关于软件质量的相关谈论中,我通常会引用一条经验法则。所以,我决定发帖总结一下。我将其称为“软件质量的黄金准则”,因为它简单明了,并且可以广泛使用。


黄金准则如下:


宁可在 upstream (上游,接近问题的根源层面) 推送补丁,也不要在 downstream (下游,远离问题根源的层面) 解决问题。


我将在本文引用 Haskell 社区和生态系统的例子,进一步解释这个准则对软件工程 tradeoffs 的影响。


免责声明:软件质量的黄金准则不代表你对待他人的黄金准则,反之亦然。

第三方依赖

很多开发者项目都借助于第三方依赖或工具,但他们却很少思考如何修改或改进这些第三方代码。相反,他们更多屈从于旁观者效应。这也就意味着如果一个项目的应用越广泛,那么开发者就会越发理所应当地认为会有人帮助他们解决一切问题。长久以往,这些开发者在面对热门工具中的问题就会熟视无睹。


举例来说,很长一段时间以来,Haskell 不支持访问资料字段的点语法。在 Java 中,如果想要修改嵌套结构资料中的数值,只需要将参照变数串起来,例如:


a.b.c.d.e = 10 
复制代码


但是,在 Haskell 中则是每多一层,每个等号就会重复之前等号的序列并多一个取值用的函数,例如:


a <- a{b=(b a){c=(c (b a)){d=(d (c (b a))){e=10}}}} 
复制代码


Haskell 社区在 downstream 通过各种方式 ,包括 lens 在内的软件包,试图模拟点语法。这种方式有好有坏,好处在于拥有一流的数据访问器,缺点则是不尽如人意的类型推理、错误信息,以及缺乏编辑器对字符完成的支持。直到最近,Neil Mitchell以及Shayne Fletcher才通过 RecordDotSyntax提案将这个功能直接 upstream 到语言中,从根本上解决了这个问题。


从“软件质量的黄金准则”角度来看,开发者应当更倾向于直接改进依赖的工具和软件包,即‘upstream 推送补丁’,而非在本地迂回,逃避问题,即‘downstream 绕过问题’。这类 upstream 改进可以直接作用于以下几点:


  • 编辑器/IDE

  • 命令行 shell

  • 所使用的编程语言

  • 所依赖的软件包


注意,upstream 解决问题的成功率并不是百分之百,尤其是当某些 upstream 不欢迎外界贡献者时,但至少也要尝试下,再说放弃。

类型化 API

函数类型同样可以遵循这个准则。假如有两种方法可以为 head 函数分配一个“安全”(总计)类型,用于获取列表中的第一个值。


第一种方法将错误推到了 downstream:


-- Return the first value wrapped in a `Just` if present, `Nothing` otherwise head :: [a] -> Maybe a 
复制代码


而第二种则将需求推到 upstream:


-- Return the first value of a list, which never fails if the list is `NonEmpty` head :: NonEmpty a -> a 
复制代码


根据黄金准则,后者应当更得人心。第二种方法的head类型签名需要一个非空输入,通过禁止用户提供空列表,从而将修复措施推到了 upstream。 更一般地讲, 如果你能践行这条规则的话,最后就会做到让非法状态无法表示


在上述例子中,前者的head类型签名则是通过返回一个Maybe来绕过可能存在的空列表。这种类型提倡在过程后期捕捉错误,错误不会在第一时间反馈,导致软件质量的降低。而如果想要提升质量,则应当直接在 upstream 中问题的根源那里快速失败,而不是根据 downstream 的问题症状位置间接调试。

社会分工

我是康威定律的坚持拥趸者,根据该定律:


设计系统的架构受制于产生这些设计的组织(广义定义)的沟通结构。

—— 马尔文·E·康威


我有时将其解读为“社会分歧导致技术分歧”。


如果社会问题是技术问题的 upstream,那么依据黄金法则,我们应当优先解决根本原因(社会摩擦),而不是试图用技术解决方案掩盖社会分歧。


Haskell 社区内的经典例子,cabal 与堆栈的分歧,源于 FPComplete 与 Cabal 贡献者之间的分歧(根据 Haskell 的 reddit 子版块反馈修正)。由于未能解决 upstream 收费贡献者与开源贡献者之间的摩擦,导致 downstream 需要通过创建并行安装工具这样的技术解决方案来尝试绕开这个问题。如此一来,Haskell 社区分崩离析,导致初次使用的新手一头雾水并且用户体验极差。


这并不意味这 Haskell 社区中的分歧可以得到解决,也许收费贡献者和开源志愿者之间的矛盾是不可调和的,但这个例子仍然说明了未能在源头解决问题对质量的明显影响。


(译注:对国人来说,一个更广为人知的例子是 12306 电子售票系统:12306 问题的 upstream 是春运期间庞大人流量与铁路客运能力之间的供求矛盾,而 downstream 则是 12306 平台本身的数据处理能力和 UI 设计质量。显然,如果前者未能得到缓解甚至恶化,则后者的改进并不会从根本上解决广大旅客购票困难的问题,顶多是消灭频繁的卡顿和崩溃现象,而代之以"平滑"的购票排队体验——简单来说,该排队还是要排的。)

结语

请注意,软件质量的黄金准则并不是要求你必须在 upstream 解决问题,该准则只是建议,如果其他选项条件相同,那么应当优先选择 upstream 修复。有时,出于其他因素的考量,例如金钱或时间的限制,不得不放弃 upstream 修复。但如果我们希望质量为上,那么还是应当尽量遵守这个准则的。


原文链接:


http://www.haskellforall.com/2020/07/the-golden-rule-of-software-quality.html


2020-08-13 16:491508
用户头像

发布了 138 篇内容, 共 74.2 次阅读, 收获喜欢 190 次。

关注

评论 1 条评论

发布
用户头像
这篇文章想表达的观点:找到问题的根源, 从根源上解决问题
2020-08-14 11:13
回复
没有更多了
发现更多内容

Jenkins流水线(pipeline)实战之:从部署到体验

程序员欣宸

Java jenkins 10月月更

【一Go到底】第十八天---函数的注意事项

指剑

Go golang 10月月更

数字货币:影响深远的创新

CECBC

C++ | bool变量值在程序运行过程中自动篡改问题解决

中国好公民st

c++ 变量 10月月更

你有真正的享受过闲暇吗?

暮春零贰

成长 时间管理 10月月更

大数据入门学习框架

Lansonli

大数据 大数据学习框架 学习大数据

来自大厂 10+ 前端面试题附答案(整理版)

loveX001

JavaScript

JS模块化—CJS&AMD&CMD&ES6-前端面试知识点查漏补缺

loveX001

JavaScript

React的useLayoutEffect和useEffect执行时机有什么不同

beifeng1996

React

滴滴前端二面vue相关面试题

bb_xiaxia1998

Vue

搭建一套 gocd 的环境

lihui

CI/CD pipeline gocd

始料未及-- 元宇宙传来好消息,全球轰动

CECBC

元宇宙持续火爆,这些问题值得思考和警惕

CECBC

PriorityQueue 源码解析(四)

知识浅谈

Queue 10月月更

new Vue的时候到底做了什么

bb_xiaxia1998

Vue

React面试八股文(第一期)

beifeng1996

React

React循环DOM时为什么需要添加key

beifeng1996

React

React源码分析(三):useState,useReducer

goClient1992

React

你真的了解redis持久化机制AOF吗?

芥末拌个饭吧

redis 后端 10月月更

元宇宙的当下与未来

CECBC

pandas如何读写源数据

芥末拌个饭吧

pandas python 3.5+ 10月月更

vivo平台化实践探索之旅-平台产品系列01

vivo互联网技术

平台化 系统平台化

元宇宙,是噱头还是创新?

CECBC

js事件循环与macro&micro任务队列-前端面试进阶

loveX001

JavaScript

聊聊运营活动的设计与实现逻辑

Java 架构 活动运营

算法基础(六)| 双指针算法及模板应用

timerring

算法 双指针 10月月更

最大为 N 的数字组合

掘金安东尼

算法 10月月更

Java三大特性(三)—多态

共饮一杯无

Java 多态 10月月更

【愚公系列】2022年10月 Go教学课程 032-结构体方法继承

愚公搬代码

10月月更

React源码分析(二)渲染机制

goClient1992

React

linux下驱动开发_红外线解码驱动

DS小龙哥

10月月更

软件质量的黄金准则_语言 & 开发_Gabriel Gonzalez_InfoQ精选文章