写点什么

软件质量的黄金准则

  • 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:491615
用户头像

发布了 150 篇内容, 共 90.1 次阅读, 收获喜欢 198 次。

关注

评论 1 条评论

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

架构实战营模块七作业

spark99

架构实战营

学生管理系统详细架构设计

swallowluo

架构实战营 「架构实战营」

56 K8S之Kubernetes监控

穿过生命散发芬芳

k8s 28天写作 12月日更

利用 Github Pages 和 Hugo 快速搭建免费的个人网站

xcbeyond

GitHub Pages Hugo 28天写作 12月日更

介绍一些拉新的具体方案

石云升

AARRR 28天写作 产品增长 12月日更

Dubbo 框架学习笔记十三

风翱

dubbo 12月日更

Golang中的runtime包

liuzhen007

28天写作 12月日更

Timsort - 混合、稳定、高效的排序算法

Geek漫游指南

算法 排序 插入排序 归并排序 Timosrt

盘点 2021|海军的 2021年终总结, 跳槽后,我收获了什么

程序员海军

年终总结 2021年度技术盘点与展望

如何命名指标和标签

耳东@Erdong

Prometheus label Metric Naming

Springboot国际化消息和源码解读

DoneSpeak

Java spring springboot

.NET6新东西---TryGetNonEnumeratedCount

喵叔

28天写作 12月日更

Docker Rootless 在非特权模式下运行 Docker

Se7en

没事-2022继续做梦

将军-技术演讲力教练

大公司生存的几把斧

圣迪

人才 组织 战略 大公司 技术委员会

设计千万级学生管理系统的考试试卷存储方案

ren

#架构实战营

Tinder系统架构

俞凡

架构 大厂实践 Tinder

发射、加速与着陆:一群科学家的奥林帕斯探索之旅

脑极体

跟着动画学 Go 数据结构之Go 实现栈

宇宙之一粟

Go 语言 12月日更

重载(overload) 和重写(override) 的区别?重载的方法能否根据返回类型进行区分?

海拥(haiyong.site)

28天写作 12月日更

HarmonyOS(鸿蒙)——滑动事件

李子捌

28天写作 21天挑战 12月日更

代码实验01:main 方法可以继承吗?

Seven的代码实验室

阿里二面 main方法

GraphQL与REST:两种API架构

devpoint

graphql REST API 12月日更

写博客的感想

为自己带盐

28天写作 12月日更

人生的意义要不断探索实现

mtfelix

28天写作

追热点

张老蔫

28天写作

我在《Effective STL》中的找到的知识点

SkyFire

c++ stl

模块三作业

浮生若梦

「架构实战营」

【CSS 学习总结】第六篇 - CSS 布局概述

Brave

CSS 12月日更

25《重学JAVA》--多线程(二)

杨鹏Geek

Java25周年 28天写作 12月日更

画饼,是领导者的基本技能

搬砖的周狮傅

管理 管理经

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