刻舟求剑

刻舟求剑

有个楚国人,坐船渡河时不慎把剑掉入河中。

他在船上用刀刻下记号,说:“这是我的剑掉下去的地方。”

当船停下时,他沿着记号跳入河中找剑,遍寻不获。

这就是刻舟求剑的故事。

听起来,这个楚国人太傻了。

这么明显的道理,居然想不明白。

然而,你笑别人的时候,其实别人也正在笑你。

要明白其中的道理,这还要从头说起。

软件,在外行人眼里,似乎很神秘。

他们看到的每一行代码,都是处于同等层次上的。

计算机只要把这些文本顺序过一遍,就能做相应的事情。

然而,在软件从业者看来,事情是复杂的。

这些文本之间是有层次关系的。

各行之前互相依赖, 牵一发而动全身。

那么,让我们随着软件规模的增长,来一探这些层次关系的建立过程吧。

我们将看到人们的认识,是随着软件规模的发展而逐渐丰富的。

没有任何技术手段,是凭空出现的。

这也提醒我们,不要过度使用不必要的技术。

技术水平应当契合软件的发展程度。

0-50行:美好的开端

如果,你实现了一个功能,写了50行代码。

那么,一屏幕就足以容纳它们了。

甚至,全部默写到另一个电脑上,也是可以的。

这里面可能包含了一些简单的控制结构,顺序,选择,循环。

所有的计算过程尽收眼底。

世界真美妙。

50-500行:提取代码片段

如果,你实现了一个功能,写了500行代码。

那么,一个文件就足以容纳它们了。

你可以把这个文件拷贝到另一个地方使用。

但是重新再写一遍代码,你是不想再做了。

随着规模的增长,函数出现的。

因为软件功能复杂了,你不得不在很多地方做相似的事情。

函数的出现,并不是为了追求花哨,而是不得已而为之。

函数式语言的世界或许并不如此。

一开始就有函数。

那么,也可以这样说,处理相同逻辑的代码片段被提取出来了。

500-2000行:隔离状态

如果,你实现了一个功能,写了2000行代码。

那么,一个文件夹就足以容纳它们了。

如果需要的话,你可以把文件夹打包发送。

对于重新建立文件,重新写代码,你都不想做了。

随着规模的增长,代码中出现了共享数据。

函数A和函数B要处理一段数据,但是函数C并不参与。

所以,把多个函数以及它们的共享数据放到一起,是个好主意。

封装和隔离,这就是面向对象程序设计的根本思想。

函数式语言的世界里,这称为闭包。

纯函数式语言的世界里,状态隐含在顺序里面,于是出现了monad这种有趣的事物。

类,其实是跟原始面向对象无关的概念。

类是产生对象的其中一种手段,是一个模板,来生成对象。

除此之外,你或者还可以使用原型,来复制出一个对象。

继承,也提供了一种代码复用方案。

但是,不分情况的坚持使用类和继承,是自找麻烦。

当然,不分情况的使用任何东西,都是自找麻烦。

2000-5000行:规范化

如果,你实现了一个功能,写了5000行代码。

那么,可能就需要一个目录结构了。

这些目录中,有可能你用到了第三方的组件。

用到了同事或自己以前的代码库。

而且你明白了,可能你正在做的这个功能本身也只是一个中间产品。

你发现了一个高大上的概念,设计模式。

好像你不用设计模式,就无法跟别人进行交流一样。

于是,有些人膜拜它,有些人无视它。

然而,两个极端都不好,我们既要了解必要性,也要了解局限性。

设计模式降低了交流的成本。

设计模式还规范化了千奇百怪的设计。

我们避免重复阅读设计细节,也能为找到解决方案提供了思路。

但是,设计模式也不完美。

模式方案,可能不是最佳方案。

大量出现的模式,使代码千篇一律,增加了冗余度。

因此,在支持元编程的语言里,几乎很少提到模式。

但是,无视模式并不能表示你精通元编程。

这是两码事。

同时,代码清理和重构也会提到日程上来。

以及相关的一些提高代码质量的手段。例如,

结对编程,代码审查,测试驱动开发等,都耳熟能详了。

于是,在这种规模的软件开发上,合作成了重要的话题。

软件项目管理,开始有用武之地了。

还是2000-5000行:世界观的转变

现在,你有了5000行代码,功能也实现了。

世界因此就美好了吗。

经验表明,事实不是如此啊。

每一次的需求变更,都会导致一定规模代码的改写。

当然灵活性,易扩展的软件架构会减小负担。

但也难免受到冲击。

随着业务的复杂化,如何定位问题,都已经成为问题了。

为了避免无止尽的重写,返工。

专门的需求分析,开始有人做了。

由于软件规模变大了,软件项目的参与者也增加了。

大家可能在同时修改代码,有的人也想看看昨天的代码是什么样的。

于是,引入了版本控制。

别人改了一处代码,结果影响了你的功能,这太常见了。

但是,怎样才能发现的早一些呢,最好在他改的时候,就告诉他。

单元测试可以帮助你。

目录结构中文件太多了,每一次集成,部署到生产环境,手动处理是很麻烦的。

如果能自动安装部署就好了。

自动化部署,也加上。

还有很多很多。

为什么会增加这么多额外的工作?

软件到底怎么了?

这些其实揭露了软件业不同于其他产业的一个显著特征。

那就是,软件是无时无刻不在变化中的。

软件是它生命期内,这个历史过程中的一个瞬间写照。

就像前文所说的刻舟求剑的例子一样,

我们应该用发展的眼光来看待软件开发。

这一事实,在软件规模足够大时,就越发明显起来了。

5000-10000行:自动化

可以说,计算机科学就是研究什么可以自动化的学科。

编程语言描述了自动化的处理过程。

自动化处理,让我们有迹可循。

在大规模软件项目中进行编码时,手动处理一切是不现实的,更是不适合的。

没有自动化的控制,我们几乎寸步难行。

我们不敢修改一行代码,因为我们无法知道后果是什么。

我们不敢修改一个类,因为它可能在成千上百个文件中都用到了。

我们不敢删除一个文件,因为它可能被某个模块动态调用。

那怎么办?

我们只能用软件本身来处理软件的问题了。

软件是用来处理复杂度的,那么当软件规模足够复杂时,

用软件来处理软件的复杂度,这种想法也是合情合理的。

所以,大规模软件项目,并不是一蹴而就的。

都有一个漫长的成长过程。

而伴随其成长的,是相关的辅助工具。

有第三方的合适工具可用的话,我们会尽量发挥软件的杠杆效应。

站在巨人的肩膀上。

如果没有的话,我们要有能力有意识的去制作工具。

人有别于其他动物的特点,不就是能制作工具吗?

我们还可以制作制作工具的工具。

这就是软件赋予我们的能力。

结语

软件是一个发展过程,

思想跟不上软件规模的发展,就会走得艰难,

而追求不切实际的技术手段,也是枉费力气。

软件的价值,在于存活期内它能为使用者带来多大效益。

这真是,春蚕到死丝方尽,蜡炬成灰泪始干呀。

就让我们把软件当做一路同行的知心朋友,

携手并肩,共同走向美好的未来吧。

相关风暴

花了一个星期,我终于把RPC框架整明白了!(深度好文)
仪城河,仪征的“城市名片”
365彩票app安卓版下载

仪城河,仪征的“城市名片”

🌧️ 07-19 👁️ 5286
十堰周末去哪玩最好,十堰带孩子、家庭、情侣周末游玩好去处
365彩票app安卓版下载

十堰周末去哪玩最好,十堰带孩子、家庭、情侣周末游玩好去处

🌧️ 07-07 👁️ 5348
苏丹国家概况
365体育封号怎么办

苏丹国家概况

🌧️ 09-24 👁️ 7414