我想到了一个类比,通过这个类比每个人都能学习到与软件设计有关的基本原则。我这个类比的独到优势在于,它囊括了你所需要了解的关于软件设计的一切知识原理。
想象你自己正在用铅条建造一座单体建筑。最终的建筑结构如下所示:
|
_|_|_|_
|
|
|
在建造完成后你可以把建筑放置于某处,它或多或少总能在某些方面派上些用场。
铅条代表的是软件中的独立组件。将建筑放置于某处类似于把软件部署在产品环境中(又或者是把它发送给你的用户)。如果你仔细思考的话不难发现,一切在建造过程中产生的有关概念也能在软件开发中对应找到。尽管你没有必要在当下阅读这段文字的时候,立即在脑海中把它们相互关联起来。假如你现在能对整个建造流程稍做想象的话,所有相关的概念都会变得清晰起来。
错误的方式
假设所有工作都需要你只身一人完成,甚至你还需要亲自制作铅条原材料。在这个前提下一类错误的建造方式大致如此:
1. 制作一根长款铅条,然后将它平放在车间的地上:
|
|
|
|
|
2. 在长铅条中钻一个孔,并测量这个孔的尺寸。
3. 制作另一根铅条,并且保证它刚好能穿过这个孔。
______
4. 让新铅条穿过旧铅条的孔,然后将它们焊接在一起:
|
__|__
|
|
|
5. 在横向铅条上钻两个孔,测量它们的尺寸,然后制作两条能各自穿过这两个孔的铅条:
| |
6. 将这两条铅条沿着孔插入横向铅条中,然后将它们焊接在一起;
|
_|_|_|_
|
|
|
7. 借助铲车将它放置于卡车中,并把它运送到目的地(因为它太重了所以你一个人没法移动它)。
8. 通过滑轮装置将它吊起,并且以垂直向上的方式放置于地面上。
9. 此时你会发现它自己没法独自垂直站立,但是你可以在它旁边放置一些依靠物作为临时解决方案,用来防止它跌落;
|
_|_|_|_
|
__|__
| | |
10. 三天之后你发现建筑物跌落摔坏了,看来临时的倚靠物体并不是长久的解决方案。
11. 不幸的是横向铅条已经部分断裂,你必须要修好它。但难点在于因为所有的铅条已经被焊接在一起了,所以无法轻易地把损坏的那根抽离出来并把它替换掉。现在要么重新建造一座新的建筑体,要么把损坏铅条的破损部分焊接修复好。将已经破损部分重新焊接起来注定会留下修复的痕迹,但这么做的成本也还是比建造新建筑低不少,所以我们还是选择焊接修复而不是从头再来。
12. 继续在建筑周围放置更坚固倚靠物保证它屹立不倒。
13. 经过一周坏天气的折磨后,焊接好的铅条早已摇摇欲坠,再一次用焊接的方式将它们修复。
14. 在六天的时间内眼看着建筑物再一次跌倒,毕竟倚靠物并不是一劳永逸的解决方案。
15. 重复最后几步直到你将所有的时间或者金钱消耗殆尽。
对错误的方式进行分析
上面的流程中有什么可取之处吗?好吧,至少我们看到独立个人也可以从无到有地仅凭一己之力将建筑建造完成。对应到软件开发中,等同于某人“写了一些能够成功运行的代码”。如果他还是个热爱工作的家伙的话,相信这也让他的工作内容充实了许多。
不好的部分有哪些呢?
-
所有的铅条必须按顺序独立定做。
-
建筑完成之后(那个没法单独直立的玩意)可能存在的问题,只有在它被建造出来并且运送至在目的地之后才能被发现。
-
当问题被发现时,只是被“紧急修复”了而已,没有长远规划如何避免灾难再次发生。
-
花费了巨大的成本将建筑转移到指定地点。
-
想要中途改变铅条配置是根本不可能做到的,因为它们已经被焊接在一起了。只能重新来过。
-
需要频繁对完成后的建筑加以留意,以防跌落。
我很肯定当中还存在不少问题,哪怕花上一整天的时间对整个类比继续分析下去都不嫌多。
总结
错误处理方式的最大问题在于,它根本无法适用于多人同时工作在这个项目上(对应于现实世界中真实的软件项目)。其中最主要的矛盾是,在锻造铅条之前你必须测量出所有孔的尺寸,所有这些工作必须由一个人按照顺序完成。
通常有两个办法解决这个问题:
1. 在开始制作铅条之前撰写一份包含全部孔尺寸的规格文档,然后再将每一种尺寸的孔所对应铅条的制作工作分配下去。
这种方法的缺陷在于需要单个人编写整个规格文档,如果项目庞大的话(想象有成千上万个孔)这项工作会耗费大量的时间。并且在规格文档完成之前团队中的其他成员都无法开始工作。完成之后文档中可能充斥着各种错误——只要孔存在,出错的概率就存在,孔的数量越多,出错的概率就越大。
2. 假设“铅条上所有孔的尺寸都相同并且位置分布一致。铅条能通过螺丝拼装在一起”。那么每个人就能依照标准的孔尺寸制作铅条(或者从商店里购买它们)。
这会让工作变得容易起来,还能允许大家并行工作。但因为你已经将铅条标准化了,你也丧失了灵活处理特殊情况的能力(也许半个尺寸的孔在某些时候更有用)。
无论如何你还是应该使用标准孔来建造建筑,那样会避免很多问题。有了标准之后,在技术规格上做一些额外的妥协,会比没有标准的时候更容易。
这个方法的重要前提是,你应该做些适当的研究来决定好的孔和好的铅条应该是什么样的。
以上并没有解决错误方式中存在的所有问题,但是它开始将我们拉向用正确方式解决问题的正轨。
正确的方式
所以在使用标准化铅条的前提下,多人并行工作的流程是什么样子?(这个流程也适用于其他产品的制造。)
1. 首先让团队中的成员制作(或者购买)标准化的独立铅条,这一步骤允许多人同时进行。
2. 人们需要对他们制作的铅条进行测试,以确保它们不会轻易损坏。
3. 人们将他们的独立铅条运往建筑所在地。
4. 把第一根铅条放在地上,直立向上:
|
5. 从各个角度尝试推动第一根铅条,看它是否会倒下。
6. 用螺丝将第二根铅条固定在第一根上:
|
|
7. 对建筑进行测试,发现它自己没法独自站稳。
8. 将牢不可破的钢索固定在建筑的两侧,类似于:
/|\
/|\
这些钢索在任何环境下都应该是坚不可摧的。
9. 再对整个建筑进行测试,确认无论你用多大力气推动它,它都屹立不倒。
10. 添加第三根铅条,同时也放置新的钢索,像这样:
/|\
//|\\
// | \\
11. 移除底部的钢索:
/|\
/ | \
/ | \
(相信任何参与过大型代码重构的人都会不约而同地觉得以上两步似曾相识。)
12. 再一次进行测试。
13. 重复这些步骤直到你将建筑完成:
|
_|_|_|_
/ | \
/ | \
/ | \
14.如果其中一根钢索在三个月内损坏了,请找出损坏的原因并且修复这个问题,将损坏钢索替换为能够适配这个孔的新钢索。保证建筑和之前一样坚固。
15.重复以上步骤直到你不需要给予建筑额外的关注,它能够独自站立。
16.可以按照用户对建筑的使用需求对建筑进行适当调整,调整的工作实施起来应该非常简单,因为所有孔都已经是标准化的了。
我们遵守了所有与软件设计有关的准则
-
我们考虑到了将来。这种思维方式贯穿在整个建造的过程当中,但只有我们把牢不可破的钢索真正地应用于固定建筑之后,才算是将这种想法付诸实践,也一并免去了我们的后顾之忧。
-
值得注意的是我们并没有尝试去预测未来,我们只是雷打不动般按照应该遵守的原则行事,最终建筑也就很轻松地建造完成了。
-
为了便于日后的重建,我们改用螺丝而不是焊接的方式对铅条进行固定。同时也在所有的铅条上放置了标准化的孔,即使我们现在可能不需要它们,但等到将来需要再添加更多的铅条时它们能派上用场。
-
在建造过程中的每一个步骤里,我们都保证了每次更改都是碎片化且经过测试验证的。例如创建单个铅条就是将任务拆分之后的其中一个环节,然后再通过小步骤将它们组装在一起。
-
我们做的最重要的一个决定,是确保整个过程足够简单。为了达成这个目标,我们让所有孔的尺寸都规范化起来,让所有操作都很简单且易于拆解。
无论你的团队只有你一个人还是有上千人,无论你的项目只有十行代码还是一千万行代码,上面的流程和准则都适用于你正在进行的软件开发。