今天是晴天。 您正在沿着通往您所有朋友,家人和挚爱狗的村庄的道路行驶。 美好的一天! 突然,您听到了可怕的噩梦般的哭声撕裂了周围的环境。 巨大的令人讨厌的九头蛇正逼近村庄摧毁它! 您抓住一把剑(当然,您有一把剑!),并尝试保护您爱的每个人。 但是有一个小问题:怪物有很多目标,而当您砍掉其中一个目标时,新的目标会迅速增长!
看来您无法赢得这场战斗。 也许您可以在Hydra上玩足够长的时间,以使整个村庄都有时间逃避可怕的威胁? 最终,您将成为全世界的真正英雄! 谁不想要这个?
Hydra在软件中的作用是熵:它是您的敌人,他使您筋疲力尽,但您永远无法完全摆脱它。 但是您仍然需要与他抗争,以便您的应用程序(和同事)保持健康和理智。
我们将发现:
- 软件中的熵是什么,以及如何在代码中注意到它。
- 其可能的原因是什么,以及如何保持较低的熵。
够说话了!
认识你的敌人

什么是熵,它如何在我的应用程序中结束?
有时,找出所用单词的词源是有用的,尤其是诸如熵之类的特定单词。 从希腊语翻译过来的意思是“转变”。 改变 您应该习惯一些软件开发人员的知识。
熵是指热力学的第二定律。 它说,在一个封闭的,孤立的系统中,混乱的数量不会随着时间的流逝而减少。 它保持稳定或增长。
软件中的熵思想是通过《
面向对象的软件工程 》一书提出的。 程序变化越多,它的混乱就越多,其熵也会增加。
可怜的开发人员需要向我们表明的第一件事是悲惨的事实:我们可以在程序中对抗熵的数量,但是我们永远都无法摆脱它。
创建最好的团队(当然需要您的参与!),最好的环境,最好的管理,公司中最好的文化,最好的项目。 随着时间的流逝会发生什么?
- 您每天早晨都会哼着“这是最好的项目!” 一个绿色的项目,看起来像一个美丽的田野,被美妙的日出照亮。
- 您和团队将添加越来越多的功能。 由于您是最好的,因此一段时间以来,一切看起来都很不错。
- 几个月或几年会过去。 没有人想再从事任何项目了。 即使设计得很好,技术已经过时,该项目也需要太多的精力和时间来理解,而且扩展规模很大。 建立他的良好心理模型太困难了。
您是如何造成这种复杂性的? 您只需要扩展项目。 更多的元素通常意味着更多的依赖性和更高的复杂性。 我已经写了
一篇详细的文章 。
如果您向开发人员Lyokha解释这一点,他将回答:
“ Nifiga! 你是傻瓜吗 混乱和混乱在我美丽的应用程序中没有位置! 我的名声不会因胡扯而受损! 我是命运的主人! 如果我不更改程序,那么复杂性将不会增加,并且结合这种矛盾的证据,我声明您是错误的,我是最棒的!”
您可以从容,说服和果断地向Lyokha解释,即使您不更改程序,其周围的所有内容也会改变。 如果您有未更新的第三方库,将存在安全问题。 如果更新它们,它将为改变和熵打开大门。
此外,如果有一天您
需要长时间修改软件,那么您将不会记住所有细节。 即使是最好的文档也不会帮您。 世界已经发生了变化,无论是在技术层面还是在业务层面,昨天的真实情况可能永远都不是真实的。
这样的变化立刻带来大量的熵。
因此,问题不在于摆脱它,而在于适度。 这是我们开发人员陷入的一场真正的战斗。
软件中熵的定义
软件质量
如何确定您的应用程序具有较高的熵? 一个好的指标是代码的质量。
它是什么以及如何测量? 根据
加速:发展背后的科学 :
- 如果更改/失败的比率增加,则质量会下降。 跟踪更改,错误和崩溃,将它们相互比较。 如果每次更改都导致新的错误或崩溃,则程序中的熵会增加。
- 开发人员对项目的主观感知可以发挥重要作用。 如果每个人都感到在不破坏应用程序的情况下扩展应用程序变得越来越困难,那么熵可能很高。 但是,这种感觉应该很普遍。
- 如果团队花费大量时间修复错误或从故障中恢复,那么熵必定会在您的应用程序中造成麻烦。
如果您可以获得有关变更与失败的比率的一些信息,并花时间修复错误,那么您可以拿出一个好的时间表来说服管理层进行某种重构。
困难恶魔
即使您拥有最高质量的代码,但就程序的功能而言,复杂度也很容易增加。 业务本身就是无法摆脱的
必要复杂性的根源。
由于业务过于复杂,开发人员将不得不花费大量精力来建立公司业务的良好
思维模式 。 因此,他们在尝试将业务需求转换为代码时会犯错误。
让我们更详细地讨论业务的复杂性:我们真的需要让我们失望的所有这些复杂功能吗?
熵的原因,以及如何处理
熵瀑布
问题
软件熵的主要原因或多或少是开发人员本身的原因。 他们很懒惰,缺乏资历,特别是与您一起工作的Sanka。 他问了很多问题!
我强烈不同意这种观点。 以我的经验,熵的主要原因是领导能力,尤其是在采用瀑布式管理风格的公司中。
正如
Gerald Weinberg在
“咨询的秘密”中指出的那样:
即使这是纯粹的技术问题,也可以始终将其起源追溯到管理的作为或不作为。
我知道您的想法:“您错了! 管理并不总是对所有事情负责! 开发人员将一切归咎于老板是很方便的!”
我并不是说领导应该为一切负责,但他总是有
一定程度的责任感 。 开发人员做得不好吗? 您需要查看招聘过程。 规范执行不力? 也许有些领导人不知道他们真正想要什么,因此规格对他来说并不重要。
因此,成为领导者是如此困难! 您在层次结构中越高,就越难。
作为开发人员,您对决策有多大影响? 如果100%,那么恭喜您,您应该为一切负责。 如果为0%,则不是您的错。 这些极点之间是整个影响范围。 而且瀑布并不意味着有很多瀑布。
使用Scrum,看板和扑克计划? 当然您不使用瀑布! 您就像孩子用螺丝刀盖房子一样使用敏捷。
当然,工具很重要,但是它们的重要性
远低于您的思维方式的重要性 ,这对于正确的软件开发是必需的。 引用敏捷清单:
个性和互动比流程和工具更重要。
使用Scrum并不意味着您正在使用敏捷,特别是如果您没有这种方法正在尝试教授的方式时。
使用瀑布管理,比您高的人可以做出决定,更高的人,其他人可以做出新的决定,依此类推。
在层次结构的较低级别上,雇员的诅咒是要遵循所有做出的决定。 他们的任务是什么? 做,好像汽车工厂的装配线上的工人。 他们不需要思考,
他们必须制造汽车 。
坏消息:作为开发人员,您将处于层次结构的底部。
如果最上层的人对应用程序的功能进行决策,而您几乎没有机会影响决策过程,那么欢迎来到瀑布! 不幸的是,大多数情况下,高级管理层没有看到
在软件开发领域中没有生产阶段 。 开发人员参与
了系统的
设计 ,而这项任务远非机舱的传送带组件。
怎么了 因为与汽车不同,应用程序在不断变化! 您需要正确
设计它们,以使其起作用,满足用户需求,应用程序具有可接受的性能,可伸缩性和耐更改性,同时将熵保持在较低水平。 为此,您需要做出许多有关如何在代码中
反映业务知识的
决定 。
如果您不影响领导层所具有的复杂性,那么您将不得不花费大量精力在代码中进行管理。 这将被认为是“必要的”复杂性:无法避免的复杂性。
可能的结果? 熵水平可以非常非常快地增长。
可能的解决方案
公司需要尽可能积极地实践共同的决策和责任。
如果您在我描述的瀑布模型中识别出您的公司,那么您需要与那些做出决定的人交谈:
- 提供数据和强有力的论据,说明为什么以及如何简化特征X或Y。说明现在和将来开发复杂特征的可能代价。
- 解释为什么敏捷软件开发意味着人们需要一起工作。 根据业务需求,经理,设计师,开发人员和其他所有人都应参与决策过程。
- 如果您的领导层自动拒绝该提议,那么您需要了解它为什么这样做。 提出问题。
- 讨论决策者认为最重要的事情:金钱和时间。 向他们表明,敏捷风格的思维(而不仅仅是工具)可以拯救您俩。
但是,如果没有被询问,则很难尝试解决该问题。 许多管理人员对瀑布模型感到非常满意,甚至常常不知道他们正在遵循瀑布模型。 您将需要大量的外交手段和技巧。
考虑到所有这些,如果您认为业务解决方案为您的应用程序增加了太多的复杂性,并且即使尝试也无法做任何事情,那么我建议您另谋高就。 这太累了-每天都以高熵工作,而使a肿的愉悦产品是远远不够的...或使用它。 这可以为您提供有关产品预期成功的提示。
最后一点:如果您对业务流程了如指掌,那么可以简化在业务级别上看起来很复杂的事情。 这是非常重要的。 因此,了解有关公司活动,他们在做什么和不在做什么的更多信息,这将有助于简化功能和代码库。
在表达架构时,我们向计算机解释了一些内容。 为此,我们需要很好地理解我们的解释。
唐纳德·惠普规范质量和技术职责
问题

除了业务引入的“必要”复杂性之外,软件的熵还与代码质量和技术负担密切相关。
什么是技术债务? 简而言之,这些是您用来节省时间的简化(黑客),您知道以后可以再次使用。 尤其是在其他功能依赖于这些hack的情况下:您将不得不以麻烦和头痛的形式,以有兴趣的方式修复它,就像背上真正的债务一样。
根据您的应用程序的任务,技术债务可能或多或少是可以接受的。 如果该程序可以运行几个月,那么您根本就不会考虑技术负担,熵或质量。 只需将代码片段放在一起,就可以完成!
例如,在从头创建更复杂的应用程序之前,这可能是一个临时解决方案。 如此一来,您可以快速编写一个原型来说明该想法,然后重写所有内容或放弃该概念。
另一方面,公司通常希望开发寿命更长的应用程序。 这是合理的:重写应用程序可能会非常昂贵(尤其是很大的应用程序),而且没人能保证它的熵级别会降低。 复制是一项非常冒险的业务。
在这种情况下,您需要非常谨慎地对待技术职责和代码质量。 这是开发人员工作的重要组成部分。
在著名的
《实用程序员》一书中(其中引入了
DRY原理 ),给出了一个有趣的技术债务类比。 这里描述了一项研究,该研究比较了窗户被打掉的城市建筑物的破坏情况。 破损的窗户给人留下被遗弃的印象,激发了该地区的每一个恶霸。 结果,窗户破损的建筑物比窗户破损的建筑物破坏得更快。
技术债务是代码的简化或破解,是一个残破的窗口。 当另一个开发人员,甚至您自己将来注意到这一点时,就会有增加更多技术债务的诱惑,因为“这里仍然存在错误的代码,那为什么要洗个澡呢?”
示例:您为一个复杂的错误编写了一种解决方法,因为没有时间去寻找它。 此替代方法之上的另一位开发人员(或您稍后自己)可能会编写不同的代码,从而解决另一个问题。 没人会很快解决的变通方法层将会增加。
解决方案
首先,您如何知道某个代码是否存在技术债务?
问问自己:
- 我可以简单 , 逻辑地解释代码的作用吗?
- 这里使用正确的名称吗? 他们是否有助于解释代码的作用?
- 是否使用带有“ and”的长名称,例如“ deleteUserAndShutDown”? 这是一个好信号,表明您需要分离函数,方法或其他某种构造。
- 感觉是否由于懒惰而添加了一些代码? 是否违反逻辑并损害理解?
您的知识和经验增长的越多,您就越好奇,与其他开发人员进行健康讨论的频率就越高,您越会注意到技术债务的形式。 这是
一个扼杀代码 。
遇到此类模式时,请勿将其视为添加更多技术债务的许可:
- 技术时间的增加将导致新的问题。 他们会回来,并会进一步追求您(和您的团队)。
- 遇到技术债务后,对其进行重构。 这是最好的选择。 如果您没有时间或精力,只需添加一条注释// TODO:为此和该原因进行重构。 报告问题,不要将其隐藏在代码库中。
不要忘记,您需要与其他功能的开发并行进行重构,以使它们与当前体系结构匹配。 简而言之,修复技术债务不应是一项独立的任务,而应是与当前任务无关的正在进行的过程。 开发功能时,赋予自己纠正遇到的技术债务的权利。
一次重构少量代码,并经常运行测试以确保系统按预期运行。
最后,在重构期间,您可能需要一些很好的参数:
- 首先,为了自己。 很容易想到您的同事无法编程,并且您比其他人更了解。 但是,如果您没有看到重构的特定好处,那就不要了。 也许整个事情只存在于你的自我中,你可以毁了一些东西。
- 如果重构与代码风格有关,则意味着您的团队尚未明确定义它。 开会,共同决定您要采用的代码样式。 这将需要记录在某个地方,以便每个人都可以根据需要进行处理。 根据团队需求编辑协议。 否则,您的代码将充满“我们使用标签!!!”之类的注释。 没有空间!!!!! 11!1 !!!”。 这是无用的声音。
- 最后,如果有人问您为什么更改他的漂亮代码,您将有真正的理由来解释您的决定。
良好的论据始终在未来发挥积极作用。 例如,包装第三方库,以便它不会导致代码库泄漏。 如果您不明白我为什么要谈论泄漏,请阅读
我写的有关抽象的文章 。
对于我们人类来说,在中长期内进行预测是困难的。 因此,考虑到未知的未来,重构或“出售”某些东西并不总是那么容易。
技术职责反映了
简单路径与
正确路径之间的二重性。 第一个是快速且有吸引力的,第二个将使您的项目可扩展且易于维护。 您将需要
自律以尽可能多地选择第二条路径。 否则,未来将充满痛苦。
如果您太累,烦恼或充满其他想法或情感,从而降低了坚持正确道路而不是简单道路的动力,那么最好不进行编程。 散步,与同事交谈,休息一下。 重新学习代码。
通常,在调试过程中会增加技术负担。 如果您通过
添加变通办法来修复错误,那么您尚未修复任何内容。 该错误仍然存在,它很难运行并意外找到它。 您需要使用
重构 ,
更改或完全
删除代码来修复错误。 然后测试代码,以确保该错误不会再次发生。
最后:责怪同事犯错误是徒劳的。 如果您对您的代码库说得不好或讽刺,这也不能解决问题,只会使情况恶化。 不要破坏团队合作精神。 您需要减少项目中的熵,而不是口头破坏它。
自动化测试
问题

在神奇的软件开发世界中,尤其是在初创企业中,有一些让我着迷的事情:许多程序员仍然不想编写自动化测试。
为什么让我着迷? 在工程的所有其他领域,他们通过遵循严格的流程来测试自己的工作。 当您制造火箭时,您需要测试许多系统,否则火箭会掉落。 汽车,桥梁,飞机也一样。
省钱 。
一个简单的例子:
NASA正在彻底测试其代码(请参阅规则5) 。
, , ,
.
, , .
. .
, , — , . ? , . , , ( ), , - .
, : ,
. ,
.
, .
解决方案
, , , .
.
- 1,3 . , . «» .
:
, , - ( ), :
- . , , .
- . , , - .
- . — , .
- , - . , - . !
- , . !
,
.
, . , . , .
, , .
.
, , . , , - .
, , . , , :
, . , . . , , , - , .
— , .
, .
,

:
. , , .
?
— . - , . , .
仅此而已! , .
, , .
, , : « , , ? , . !».
: , . , . , .
, , , . , , . !
. :
, . , . , , .
, , . ?
, . , , .
:
- , . «, ?» — , « ! ! !».
- , . , , , , . «, , ?» « , 289 ».
, . ,
!
( !) .
. , , .
, — , , . !
!

, , , ,
. ? ? - ? ?
. , . -, . , , , .
, , . . — .
这样啊 ?
- — . . , .
- — .
- . / .
- , , .
- , . , .
- 通过联合编程,代码分析,或简单地设置指向有趣的信息源(文章,书籍)的链接,营造一种易于彼此共享知识的氛围。
理想的软件不存在。熵永远是我们工作的一部分。这并不意味着我们已经输掉了这场战斗。这意味着减少整个代码库中的熵已经是胜利!有用的链接: