看起来简单, 实际上复杂

作者: 周思博 (Joel Spolsky)
译: Bo Yang 翻译
编辑: Billy Chen 编校
2002年3月4日

我们在CityDesk里有一个使用性上的小问题。

问题是这样的:你可以用菜单上“导入网页”的命令,从因特网上导入一个文件。你也可以用鼠标拖放的方法,从磁盘上导入一个文件。但是菜单上没有“导入磁盘文件”这个命令,所以有些用户没有发现CityDesk 有这个功能,或者他们试图用“导入网页”这个命令去导入磁盘上的文件,结果造成无法成功导入。

我一开始想这个问题很好解决,大概的方法就是用一个两个页面的文件导入向导。第一页问你:“你要从哪里导入?”。如果你选择“磁盘”,第二页就会提示你选一个文件;你要是选择“因特网”,第二页就会提示你输入一个URL.

我差点就开始动手去实现我这个想法了,但是有些事情使得我并没有这样做。我决定先写一个小的规约再说。写出来的规约如下:

第一页

你要从哪里导入?

磁盘/因特网

第二页(磁盘)

标准的打开文件对话框

第二页(因特网)

用小浏览器让你输入一个URL

突然间我想到一个问题。Windows的打开文件的对话框,通常是由操作系统提供的。能不能把这个对话框放到我的文件导入向导里面呢?

嗯…

我查了一下。是可以这样做的,但这不是一件好玩的事,而且要花好几个小时的时间。我能不能不使用导入向导的方式呢?我重写了一下我的规约:

两个菜单项:

1)从网上导入网页 -> 显示URL输入对话框

2)从磁盘上导入网页–> 显示打开文件对话框

这就好多了。三分钟的设计时间,省了我几个小时的编程序时间。

如果你这辈子花了二十分钟以上的时间去编软件代码的话,你就可能发现了一条规则:事情没有看起来那么简单

就像拷贝文件这样简单的事,都充满了危险。如果第一个参数是个目录会如何?如果第二个参数是个文件会如何?如果同名的文件已经存在于目的子目录会如何?如果你没有写的权限又会如何?

如果在拷贝文件的过程中失败了怎么办?如果目的地是在一个远程计算机上,但是需要身份验证怎么办?如果文件很大但网络连接又慢,所以你需要显示一个进度条怎么办?如果文件传输速度降到几乎是零了,你什么时候放弃拷贝而给用户一个错误信息呢?

一个面试测试员的好办法,就是给他们一个简单的操作过程,然后让他们列出可能出现的错误情况。一个在Microsoft面试时典型的问题就是:你怎样去测试打开文件对话框呢?一个好的测试员,可以轻而易举地列出几十个令人难以想到的情况去测试(比如“一个文件显示在对话框里,然后你去打开它,但是在你按打开的按钮之前,这个文件被另一个用户删除了”)。

好,我们得到这样一个公理:事情没有看起来那么简单。

软件工程里还有一个指导思想,那就是你要永远想方设法去减低风险性。一个要特别小心去避免的风险,就是项目进度延期的风险。项目延期很不好,因为老板会训你,闹得你挺不高兴的。除此之外,这也存在经济方面的原因,那就是当初你决定给你的软件加某个功能的时候,你觉得这个功能只需要一个星期就能完成。现在你认识到该功能需要二十个星期才能完成,那么你当初的决定当然就是错的。如果你当初就知道需要花掉二十个星期的话,你可能就作出不同的决定了。你作出的错误决定越多,你公司的财产被一次性冲销处理的可能性就越大(甚至你们公司的标志会被收入债权人的仓库)。到时候你的前老板抱怨道:“我们公司关门倒闭了不说,气人的是连上fuckedcompany的资格都没有。”

事情没有看起来那么简单,再加上减低风险性的指导思想,只能让你得出如下的结论:

先设计再编程序,先思而后行。

让你失望了,很抱歉。我知道你读过Kent Beck的书,所以你以为动手之前不做设计是可以的。对不起,那是不可以的。你修改程序不可能像修改设计文件那样“容易”。有些人总是发表这样的谬论:“我们现在用高级工具了,像Java和XML。 我们在几分钟之内,就可以改动程序里的很多东西。为什么不在程序里直接设计呢?”哥们儿,你可以在你自行车上加个发动机,但你不能把它变成汽车。如果你以为把你拷贝文件的程序,由线程式改为抢占式,而且改得比我写这句话还快,那你就大错特错了。

不管怎么说,我不认为Extreme Programming是在鼓吹零设计的理念。他们只是说:“不要作任何无必要的设计”,这没有什么错嘛。但人们听到的并不是这样。大多数程序员是在找不用设计的借口,所以他们像飞蛾扑火般投向“不用设计” 这个馊主意。这是一种奇怪的,让你事倍功半的懒惰方式。我懒得先在纸上把这个功能给设计好了,所以我就先写程序,然后发现不对,我就去改,结果反倒花更多的时间。或者,更经常发生的是,我先写些程序,发现它不对,但是没时间改了,结果我的产品质量低劣,而且我还是要找出些借口,说明它为什么“一定要那样“。那只不过是马虎潦草,缺乏职业精神。

Linus Torvalds攻击设计的时候,他是在讲那些规模庞大的系统。大规模的系统必须慢慢进化,要不然它们就变成Multics了。他不是在说你那个拷贝文件的程序。你再想想,Linus Torvalds脑子里有一个很清楚的路线图,知道他要到哪去,所以他觉得设计没什么用,也不足为奇。但不要上当,基本上说那对你不适用。Linus Torvalds比我们聪明多了,所以他能干的事,不等于我们一般人也能干。渐增式设计及实现是好事。频繁地发布版本是可以的(但针对在大众市场上的软件来说,频繁发布版本会使用户不高兴,绝不是个好主意——可以多搞些内部的里程碑取而代之)。设计上不要拘泥于形式,那只是浪费时间。我从来没有见过某个项目得益于不动脑筋的流程图、UML、CRC,或者其他什么时髦的,花里呼哨的设计方法。至于那些Linus Torvalds说的系统,那些有一千万行代码程序的庞然大物,它们应该慢慢进化,因为人类还不知道怎样设计那种规模的软件。

但是当你坐下来写你的拷贝文件的程序,或者计划给你的软件下个版本增添功能的时候,你一定要先作设计。不要让报急的号角使你草草动手。

看起来简单,实际上复杂相关推荐

  1. java代码编写的文本特征提取_Test1 java语言写的特征提取源代码,有搞文字识别的可以下载一看,简单易学 Develop 274万源代码下载- www.pudn.com...

    文件名称: Test1下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 35 KB 上传时间: 2015-03-02 下载次数: 46 提 供 者: 常杰 详细说 ...

  2. 大一计算机考试挂了怎么办,大一期末考试最容易挂科的课程,看起来简单,实则让考生头疼...

    如今已近年关,各大高校已经或者还在组织期末考试,有些大一学生还在进行着最后的冲刺.每年都有很多大一考生因为各种各样的原因导致挂科,有人可能觉得挂科的是高数.大学英语这类让很多人头疼的科目,然而事实并不 ...

  3. Asp.Net customErrors与httpErrors的区别 先看一下简单的对比

    [转]Asp.Net customErrors与httpErrors的区别 https://www.cnblogs.com/TiestoRay/p/4723996.html 先看一下简单的对比 cus ...

  4. 美容院会籍管理,看着简单,其实很复杂

    会籍管理是会员制管理的基础,广泛应用于商场.宾馆.健身中心.酒家等消费场所,差不多服务型行业都采用会员制.做服务型行业软件必须了解会籍管理. 本人从事美容院软件开发2年多,接触各种会员制形式,都不断完 ...

  5. 结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂

    三种工厂模式的详解: 简单工厂模式: 适用场景:工厂类负责创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑不关心 缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的 ...

  6. python 创建文件_Python入学首次项目,新手必看,简单易操作

    继昨天文章python软件pycharm安装教程之后,今天则给新手小白们分享一哈,怎么制作并创建文件.print "hello world": 如后期需要资料文件的则可以私信留言, ...

  7. 卸载idea2020删除以前的配置_系统瘦身指南:卸载软件,看着简单,实际贼困难...

    人们常说:"对于计算机来说,硬件是躯体,软件是灵魂.""没有软件,电脑就发挥不出它强大的功能."把这句话加强一下,那么就是: 上而施脑多件, 脑无力为足成. 算 ...

  8. 在conda虚拟环境中配置cuda+cudnn+pytorch深度学习环境(新手必看!简单可行!)

    本人最近接触深度学习,想在服务器上配置深度学习的环境,看了很多资料后总结出来了对于新手比较友好的配置流程,创建了一个关于深度学习环境配置的专栏,包括从anaconda到cuda到pytorch的一系列 ...

  9. 自己写一个代理绕过公司网络限制,听歌、看电影,实际上就是所有代理的原理,不仅仅是这些功能

    文章目录 1.能实现的功能和目的 2.整个代理思路(一次理顺) 3.详细实现过程(带截图) 3.1.首先,需要安装谷歌浏览器,网站是在谷歌浏览器上打开. 3.2.下载SwitchyOmega插件,然后 ...

最新文章

  1. ActionScript 3.0 编程精髓 示例源码下载
  2. mapreduce工作流程_详解MapReduce中的五大编程模型
  3. imdb导mysql_keras如何导入本地下载的imdb数据集?
  4. python函数调用位置_python函数定义,调用,传参,位置参数及关键字参数,返回值
  5. Lecture 14 Competive Analysis
  6. http://my.oschina.net/huangyong/blog/372491?fromerr=hobPLCmQ#OSC_h2_5
  7. shell脚本显示颜色的设置
  8. 加密软件不能安装软件
  9. 基于qt平台的ip地址输入控件
  10. 基于pywifi库的暴力破解wifi方法
  11. 第1章.绪论(计算机科学导论)
  12. 中标麒麟Neokylin7桌面版安装指南——基于VirtualBox虚拟机
  13. 重装系统win10安装教程(超详细)
  14. Excel如何动态获取某个产品最新的库存信息
  15. 电磁场与电磁波 试题含答案
  16. 高中数学怎么学好学好高中数学的技巧
  17. 周鸿祎:写区块链最好的一篇文章
  18. uniapp结合萤石视频ezuikit.js的爬坑记录
  19. 字节跳动日常实习一二三面面经(后端开发)
  20. 隐藏文件去掉隐藏属性

热门文章

  1. 在 Arch Linux 上使用人脸识别(howdy)来登陆和认证
  2. JTAG和SWD定义
  3. 神经网络翻译是什么意思,神经网络用英文怎么说
  4. C语言实现24点小游戏
  5. 智能运维探索:有一种多指标异常检测方案,你可能没用过...
  6. 项目计划表格甘特图_项目管理:什么是甘特图?
  7. java百元买百兔 穷举法_JAVA--算法与数据结构- 逢7过百钱白鸡不死神兔【1/100】...
  8. 吴恩达新课 医学图像AI(AI for Medicine)专项课程推荐
  9. mac 上传ftp服务器文件大小,mac与windows通过ftp传输文件
  10. Threejs围墙动画