人们在围绕软件开发的讨论中,几乎不可避免会随口引用一两条原则。
你可能听过人们说:“这行不通,因为‘X法则’!”。或者“你不知道‘Y原则’吗?”你是哪种类型的软件开发人员?
有许多规律和原则可以引用,其中大部分都基于真理。然而,盲目地使用像上面这样的绝对陈述来应用它们肯定会导致自负和失败。
本文列举了一些可以应用于软件开发的最流行的规律和原则。对于每条定律,我们将快速讨论其主要内容,然后探讨如何将其应用于软件开发(也许何时不应该)。
1.帕累托法则(80/20 法则)
内容
帕累托法则指出,通常 80% 的结果来自 20% 的原因。数字 80 和 20 无论如何都不是精确的,但该原则的总体思路是结果通常分布不均。
我们可以看到生活的许多领域遵守着这条规则,例如:
世界上最富有的 20% 的人创造了世界 80% 的收入。
80% 的犯罪是由 20%的罪犯所为(自 2020 年以来)。
我们知道 80% 的病毒传播来自 20% 的受感染人群。
如何应用在软件开发中?
我们可以从帕累托法则中获得的主要好处是专注。 它可以帮助我们专注于重要的事情(20%),而不是在不重要的事情(其他 80%)上浪费时间和精力。 不重要的事情对我们来说往往很重要,因为这样的事情总是有太多(而且看起来很紧急) 。但是最好的结果往往是通过关注重要的少数来达成的。
在软件开发中,我们可以使用它来专注于构建正确的功能,例如:
- 专注于实现 80% 产品价值的那 20% 的产品功能。
- 专注于导致 80% 用户使用异常的那 20% 的错误。
- 专注于实现 80% 的产品功能需要的那 20%总构建时间
-
……
只要问“现在最重要的事情是什么?”就可以帮助建立下一个最重要的事情,而不是下一个最紧急的事情。
顺便说一下,敏捷和 DevOps 等现代开发方法有助于获得这种关注!具有定期用户反馈的快速迭代允许对重要事项进行数据驱动的决策。诸如基于主干的带有功能标记的开发之类的实践可以帮助软件团队实现这一目标。
2.破窗定律
内容
破碎的窗户会招致破坏,因此很快所有窗户都被打破。
一般来说:混乱会招致更多的混乱。
如果我们的环境是原始的,我们就会有动力保持这种状态。环境中的混乱越多,我们添加混乱的门槛就越低。毕竟已经混乱了……谁在乎我们是否再添加一点呢?
我们可以从这条规则中获得的主要好处是我们应该意识到我们周围的混乱。如果它已经到了人们习惯于不再关心它的程度,那么最好为混乱带来一些秩序。
如何应用在软件开发中?
在软件开发中,我们可以将其应用于代码质量:我们引入代码库的每一种代码异味(Code Smell)都会降低我们添加更多代码异味的门槛。我们应该 [[Start Clean]] 并保持代码库干净以避免这种情况发生。许多代码库如此难以理解和维护的原因是,破窗已经悄然出现并且没有足够快地修复。
我们也可以将这个原则应用到测试覆盖率上:一旦有一定数量的代码进入了未被测试覆盖的代码库,就会添加更多未被覆盖的代码。这是保持 100% 代码覆盖率(应该覆盖的代码的)的论据,因此我们可以在窗口破裂之前看到裂缝。
3.奥卡姆剃刀(简约法则)
内容
哲学剃刀是一种通过消除(或“削除”)不太可能的假设来帮助解释某些事情的原则。 奥卡姆剃刀表示,如果有多个假设,我们应该选择假设条件最少的假设(这很可能是解释最简单的假设)。
如何应用在软件开发中?
我们可以在事件分析中应用奥卡姆剃刀。你可能遇到过这样的情况:用户报告了 你 的应用程序存在问题,但 你 不知道导致问题的原因。因此, 你 正在搜索日志和指标,试图找到根本原因。
下次用户报告错误时,请维护事件调查文档。写下 你 对导致问题的原因的假设。然后,对于每个假设,列出事实和猜想。如果假设被证明是正确的,则将其标记为事实。如果一个假设被证明是错误的,请将其从文档中删除或将其标记为错误。在任何时候, 你 现在都可以将时间集中在最可能的假设上,而不是浪费时间转移注意力。
4.邓宁-克鲁格效应
内容
邓宁-克鲁格效应表明,没有经验的人往往会高估自己的能力,而有经验的人往往会低估自己的能力。
你不擅长某件事,但你会认为你擅长它。如果你擅长某事,你认为你不擅长 - 这可能导致冒名顶替综合症,这让你怀疑自己的能力,以至于你在其他具有相似技能的人中感到不舒服 (害怕别人认为你说的不正确)。
如何应用在软件开发中?
意识到这种认知偏差已经是朝着正确方向迈出的良好一步。它将帮助 你 更好地评估自己的技能,以便 你 可以寻求帮助,或者克服自我怀疑并自己行动。
有助于消除邓宁-克鲁格效应和冒名顶替综合症的一种做法是结对或群体编程。 你不是独自工作,沉浸在自我怀疑或优越感中,而是与其他人密切合作,边工作边交流思想、学习和教学。
不过,这只适用于安全的环境。在个人主义被美化的环境中,结对或群体编程会导致更多的自我怀疑或更多的优越感妄想。
5.彼得原理
内容
彼得原理指出,只要你在工作中表现出色,你就会得到晋升,直到你晋升得到一份你不称职的工作。由于你不再成功,你将不再获得晋升,这意味着你将生活在一份不会给你带来满足感或成功的工作中,通常是在你的余生中。前景黯淡!
如何应用在软件开发中?
在软件开发中,当你将角色从开发人员职业转换为管理职业时,彼得原则通常适用。 然而,成为一名优秀的开发人员并不一定意味着你是一名优秀的经理。或者,你可能是一名优秀的经理,但不要在开发人员的工作上获得经理工作的满足感,这意味着你没有全力以赴(这就是我的情况)。在任何情况下,你都很悲惨,在你面前的职业道路上看不到任何未来的发展。在这种情况下,退后一步想想,你希望你的职业是什么样子的。然后,转换角色(或公司,如果需要)以获得 你 想要的角色。
6.帕金森定律
内容
帕金森定律指出,工作总是会填满分配给它的时间。如果你的项目在两周内有截止日期,则该项目将不会在此之前完成。可能需要更长的时间,是的,但绝不会少于我们为它分配的时间,因为我们正在用不必要的工作或拖延来填补时间。
如何应用在软件开发中?
帕金森定律的主要驱动因素是:
- 拖延症(“截止日期太远了,所以我现在不需要匆忙……”)
- 范围蔓延(“当然,我们可以添加这个小功能,它不会花费我们太多时间......”)
为了对抗拖延,我们可以在几天而不是几周或几个月内设定最后期限。 比如说在接下来的 2-3 天内需要做什么才能朝着目标前进?一个(健康的!)截止日期可以给我们足够的动力,不要陷入拖延症的低谷。为了防止范围蔓延,我们应该非常清楚地了解我们试图通过项目实现的目标。成功的衡量标准是什么?这个新功能是否会增加这些指标?那么如果每个人都明白这项工作需要更长的时间,我们应该添加它。如果新功能与使命宣言不匹配,请抛弃它。
7.霍夫施塔特定律
内容
霍夫施塔特定律指出“它总是比你预期的要长,即使你考虑到霍夫施塔特定律”。即使你了解了这条定律,并增加了项目的时间分配,它仍然会比你预期的要长。 这与帕金森定律密切相关,即工作总是会填满分配给它的时间。 只是霍夫施塔特定律说它填充的时间超过了分配的时间。
这条定律得到了心理学的支持。我们容易犯所谓的“计划谬误”,即在估算工作量时,我们通常不会考虑所有可用信息,即使我们认为我们已经考虑了。我们的估计几乎总是主观的,很少是正确的。
如何应用在软件开发中?
在软件开发中(以及任何其他基于项目的工作,真的),我们人类的乐观主义占了上风。估计几乎总是过于乐观。 为了减少霍夫施塔特定律的影响,我们可以尝试尽可能客观地进行估计。 写下关于项目的假设和事实清单。将每个清单元素标记为假设或事实,以使数据质量可见并管理预期。不要依赖直觉,因为每个人的感受都不一样。写下估算值,让你的大脑思考它们。将它们与其他人的估计进行比较,然后讨论差异。
即便如此,它仍然只是一个估计,很可能不能反映现实。如果估算不是基于统计数据或其他历史数据,那么它的价值就非常低,因此与要求你估算的人一起管理预期总是好的——这总是会出错的。如果你让它尽可能客观,它就会减少错误。
8.康威定律
内容
康威定律指出,组织创建的任何系统都将类似于该组织的团队和沟通结构。如果你有 10 个团队在一个系统上工作,你很可能会得到 10 个相互通信的子系统。
如何应用在软件开发中?
我们可以应用所谓的逆康威机动:创建最能支持我们想要构建的系统架构的组织结构。 没有固定的团队结构,而是要有足够的灵活性来创建和解散团队,这对系统的当前状态是最好的。
9.墨菲定律
内容
墨菲定律说,任何可能出错的事情,都会出错。它经常在意外发生后被引用。
如何应用在软件开发中?
软件开发是一个容易出错的职业。出错的主要来源是bug。没有任何软件不存在挑战用户耐心的错误或事件。我们可以通过在日常软件开发实践中养成减少错误影响的习惯来抵御墨菲定律。 我们无法完全避免错误,但我们可以而且应该减少它们对用户的影响。 对抗墨菲定律最有用的做法是特征标记。
如果我们使用像 LaunchDarkly 这样的功能标记平台,我们可以在功能标记后面将更改部署到生产中。然后,我们可以使用有针对性的发布来激活内部 dogfooding 的标志,然后对少量友好的 Beta 用户发布,最后将其发布给所有用户。通过这种方式,我们可以从越来越关键的用户群体那里获得关于变化的反馈。如果更改出错(并且在某些时候会出错),影响很小,因为只有一小部分用户组会受到它的影响。而且,该标志可以快速关闭。
10.布鲁克定律
内容
在经典著作“人月神话”中,弗雷德·布鲁克(Fred Brook)有句名言:为迟到的项目增加人力会使项目更晚。尽管本书讨论的是软件项目,但它适用于大多数类型的项目,甚至是软件开发之外的项目。 添加人员不会提高项目速度的原因是项目的通信开销随着添加到项目中的每个人呈指数增长。 2个人有1条通信路径,5个人已经有120条可能的通信路径。新人安顿下来并确定他们需要的沟通路径需要时间,这就是为什么在项目中添加新人时,迟到的项目会更晚。
如何应用在软件开发中?
很简单。 更改截止日期,而不是将人员添加到已经迟到的项目中。 对在软件项目中增加新人的期望要切合实际。将人员添加到项目中可能会在某个时候提高速度,但并非总是如此,当然也不是立即。人员和团队需要时间来适应日常工作,而在某些时候,工作无法充分并行化,因此增加更多人是没有意义的。仔细考虑一个新人应该完成什么任务,以及在将该人添加到项目中时你期望什么。
11.波斯特定律
内容
Postel 定律也被称为稳健性原则,它指出你应该“在你所做的事情上保守,在你接受别人的事情上开放”。 换句话说,你可以接受多种不同形式的数据,以使你的软件尽可能灵活,但你在处理这些数据时应该非常小心,以免因无效或恶意数据而危及你的软件。
如何应用在软件开发中?
该定律源于软件开发,因此非常直接适用。你的软件与其他软件或开发人员之间的接口应允许不同形式的输入以实现稳健性:
- 为了向后兼容,新版本的接口应该接受旧版本和新版本的数据
- 为了更好的用户体验,UI 中的表单应该接受不同格式的数据,这样用户就不必担心格式。
但是,如果我们愿意接受不同格式的数据,我们在处理这些数据时就必须保守。 我们必须审查无效值,并确保我们不会因为允许太多不同的格式而损害系统的安全性。 SQL 注入是一种可能的攻击,它是通过对用户输入过于宽松而造成的。
12.克奇霍夫原理
内容
Kerchkhoff 的原则指出,加密系统应该是安全的,即使它的加密方法是公开的。只有 你 用来解密某些东西的密钥才需要是私有的。
如何应用在软件开发中?
这很简单,真的。 永远不要相信要求其加密方法是私密的加密系统。 这被称为“默默无闻的安全”。像这样的系统本质上是不安全的。一旦该加密方法向公众公开,它就容易受到攻击。
13.莱纳斯(Linus)定律
内容
在关于 Linux 内核开发的《大教堂与集市》一书中,埃里克·雷蒙德(Eric Raymond)写道:“有足够多的眼睛,就可让所有问题浮现”。他将此称为“莱纳斯定律”以纪念莱纳斯·托瓦兹。这意味着如果很多人看代码比很少人看代码可以更容易地暴露代码中的错误。
如何应用在软件开发中?
如果你想摆脱错误,请让其他人查看你的代码。 源于开源社区的一种常见做法是让开发人员提出包含代码更改的拉取请求,然后让其他开发人员在将拉取请求合并到主分支之前审查该拉取请求。
这种做法也进入了闭源开发,但根据 Linus 定律,拉取请求在闭源环境(只有少数人查看它)中的作用不如在开源环境中(其中可能很多贡献者都在看它)。其他为代码添加更多眼睛的做法是结对编程和群体编程。至少在闭源环境中,这些在避免错误方面比拉取请求审查更有效,因为每个人都参与了代码的初始阶段,这为每个人提供了更好的上下文来理解代码和潜在的错误。
14.沃斯定律
内容
沃斯定律指出,软件变慢的速度比硬件变快的速度要快。
如何应用在软件开发中?
不要依赖强大的硬件来运行性能不佳的代码。相反,编写经过优化以表现良好的代码。这必须与 (软件开发定律:克努斯的优化原则) 的格言相平衡,该格言说“过早的优化是万恶之源”。 与为用户构建新功能所花费的精力相比,不要在使代码运行得更快上花费更多的精力。 通常,这是一种平衡行为。
15.克努斯的优化原则
内容
Donald Knuth 在他的一部作品中写了“过早优化是万恶之源”这句话,这句话经常断章取意,并被用作根本不关心优化代码的借口。
如何应用在软件开发中?
根据 Knuth 定律,我们不应该浪费精力过早地优化代码。然而,根据沃斯定律,我们也不应该依赖硬件足够快来执行优化不当的代码。最后,这就是我从这些原则中得出的结论:优化可以轻松完成的代码,无需太多努力:例如,编写几行额外代码以避免经历可能包含大量项目的循环。 优化一直在执行的关键业务的代码。 除此之外,不要在优化代码上花太多精力,除非你已经确定了一个性能瓶颈。
16.保持怀疑
定律和原则是好的。这使我们能够从某个角度评估某些情况,如果没有它们,我们不可能了解这些情况的背后道理。然而,盲目地将定律和原则应用于每种情况是行不通的。每一种情况都会存在微妙的变化,这可能意味着某个原则不能或不应该适用。 对你遇到的原则和定律保持怀疑。世界不是非黑即白的。