异常驱动的开发(Exception-Driven Development)
你的网站或应用程序存在哪些问题?如果你在等着用户来告诉你,那么你只能看到所有的问题中已经暴露的那极小的一部分。要知道,那只是“冰山一角”!
而且,如果你真的是在守株待兔,我不得不很抱歉地告诉你,你有点失职——你应该比用户更了解你的程序的健康状况。每当有用户告诉我一个他们在使用我的软件的过程中碰到的“善意的错误”时,我总会感到局促不安。甚至有些惭愧。我没有在用户把问题告诉我之前发现它们,并且事先解决它们,这就是我的失职。我忽视了对程序崩溃应付的责任。
任何负责任的软件项目,首先要做的事是建立一种异常和错误报告机制。Ned Batchelder把这比作为“先给自己戴好氧气罩,然后再帮小朋友戴”:
当你的程序出现问题时,请你总是先去检查这个错误是否被适当处理了。如果没有被适当处理,那么先去解决错误处理代码里的问题。保持这个工作顺序很重要,原因有如下几方面:
- 在根源错误还在的情况下,你实际上为错误处理代码中的bug准备了一个完美的测试用例。但如果你先把根源问题解决了,你又将怎样来测试你的错误处理代码呢?记住,你的代码里之所以有bug,部分原因就是它在当初的开发阶段很难被测到。
- 一旦根源问题被解决了,解决错误处理代码里的问题的紧迫性便随之消失。你可能会说,“我以后会去解决的,现在急啥?”就好比你家屋顶漏了——下雨的时候,你没办法去修屋顶,因为外面正下着雨呢;但雨停了之后,家里又不漏水了(不急着去修屋顶了)!
你需要集中在一个地方去处理所有的错误。这个地方是你团队里的所有开发人员非常熟悉的,并且每天都会接触到。在Stack Overflow,我们采用了ELMAH(https://code.google.com/p/elmah)的一个自定义分支。
我们每天都在监视着这些异常日志;有时候每个小时都察看。这些异常日志实际上已经成为了我们团队的To-Do列表(待办事项)。我们这么做是有充分理由的。比如,微软收集类似的这种错误日志已经几年了,他们不仅收集自家软件的日志,还收集第三方软件的;他们的这个机制叫Windows Error Reporting(简称WER)。成效喜人啊:
当最终用户遇到程序崩溃时,他们会看到一个对话框,问他们是否想发送错误报告。如果他们选择发送,WER会收集应用程序以及发生崩溃的模块的信息,然后把这些信息通过一个安全服务器发送给微软。
于是,软件厂商可以访问到关于他们产品的数据,再加以分析,定位到问题的根源。他们可以通过错误对话框与用户交互,还可以通过Windows Update升级他们的程序。
在对错误报告数据的广泛分析之后,我们看到:80%的客服问题在修复了用户报得最多的20%的bug之后就能得到解决。即使只修复用户报得最多的1%的bug,也能解决50%的客服问题。这个分析结果通常对于各家公司都是成立的。
尽管我仍然推崇“测试驱动开发”(Test-Driven Development,缩写为TDD),但时间投入的投机性一直是我纠结的一个问题。如果你修复了一个真实用户永远也碰不到的bug,那你的修复有什么价值呢?我知道还有很多其他的理由促使我们去实践TDD,但若单纯作为一种修复bug的机制,在我看来,选用TDD就大可不必了;就像我们过早地进行代码优化一样,是不可取的。我更愿意把时间花在解决真实发生的问题上,而不是那些理论上存在的bug。
当然,你可以两者都做。但考虑到开发时间总是有限的,我更倾向于立足于实实在在的数据,把时间花在解决真实用户在使用我的软件过程中碰到的问题上。这就是我所谓的“异常驱动的开发”(Exception-Driven Development)——将你的软件发布出去,让尽可能多的用户使用它,然后一心一意地研究他们产生的错误日志。使用那些异常日志去找出问题的根源,并且专注在你的代码中有问题的区域。重新架构,重构代码,以消除最严重的3个问题。快速迭代,部署,如此周而复始。这种数据驱动的反馈机制是非常有效的,几个迭代下来,你的程序将非常稳定,坚如磐石。
异常日志可能是用户能够提供给你的最强有力形式的反馈。这种反馈基于已经发布的软件,为了得到它们,你不必去询问用户或者诱导他们,也不必理会他们关于问题的不可思议、似是而非的描述。真正的问题伴随着转储出来的堆栈跟踪信息,已经悄悄地为你自动收集好了。异常日志才是用户反馈中的根本。
(译者注:2009年4月16日,DareObasanjo与Scott Koon @lazycoder在Twitter上有过一次辩论;Dare Obasanjo的观点是:通过将产品发布出去,然后从客户那里得到真实的反馈,这比任何事先的沟通或调研更有价值。)
我是在提倡发布带有bug的代码吗?或者半成品?或者狗屎软件?当然不是!我的意思是说,你越快将你的软件推到真实用户的面前,你就会得到越多的数据以改进你的软件。异常日志在这个过程中扮演着很重要的角色,同样地,用户使用数据也很重要。当然,如果你受得了的话,你还应该跟用户交谈。
不管怎么样,软件在发布的时候总是会带有bug的。所有软件都是这样。只要是软件,它就会崩溃,它就可能丢失数据,它还会难以学习、难以使用。问题不在于你在发布软件的时候带出去了多少bug,而在于你能多快地修复那些bug?如果你的团队一直在践行异常驱动的开发模式,答案就很简单了——别担心,我们马上就会改进我们的软件!看着吧,我们会越做越好!
听起来多美妙啊!就像一首美妙的乐曲,在每个用户的耳边萦绕……
异常驱动的开发(Exception-Driven Development)的更多相关文章
- 【翻译稿】Behavior Driven Development (BDD)行为驱动开发
这是一篇翻译稿,方便给不知道BDD的同学扫盲.原文链接:What is BDD (Behavior Driven Development)? | Agile Alliance Definition定义 ...
- Bug驱动开发(Bug-driven development)
说实话,作为一个Domino开发者,像測试驱动开发(Test-driven development).功能驱动开发(Feature-driven development)之类软件开发的高大上的方法论( ...
- 敏捷软件开发 Agile software Development(转)
原文链接: http://www.cnblogs.com/kkun/archive/2011/07/06/2099253.html 敏捷软件开发 Agile software Development ...
- 编写高质量代码改善C#程序的157个建议[用抛异常替代返回错误、不要在不恰当的场合下引发异常、重新引发异常时使用inner Exception]
前言 自从.NET出现后,关于CLR异常机制的讨论就几乎从未停止过.迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题.其实,这里存在认识上的误区,因为正常控制流程下的代码运行并不会出现问题, ...
- Java异常:选择Checked Exception还是Unchecked Exception?
http://blog.csdn.net/kingzone_2008/article/details/8535287 Java包含两种异常:checked异常和unchecked异常.C#只有unch ...
- S3C2440触摸屏驱动实例开发讲解
出处:http://www.embeddedlinux.org.cn/html/yingjianqudong/ 一.开发环境 主 机:VMWare--Fedora 9 开发板:Mini2440--6 ...
- Vs2010 配置驱动的开发环境
我已被用来VS2010开发环境,之前曾经与vs2010驱动的开发环境.重装系统,一次又一次的配置,找了好几篇文章,配置没有成功,在配置阶段突然成功了,直接把原来的驱动程序的配置文件将能够接管使用. 当 ...
- hibernate异常:org.hibernate.exception.GenericJDBCException
异常:org.hibernate.exception.GenericJDBCException 提示:Cannot open connection 提示:不能打开链接 一般这个异常是由 java.sq ...
- Atititjs javascript异常处理机制与java异常的转换.js exception process
Atititjs javascript异常处理机制与java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw err ...
随机推荐
- ionic3-ng4学习见闻--(多语言方案)
1.安装ng2-translate npm install ng2-translate --save 2.app.moudle.ts 引入模块,在下方新增方法 import { TranslateMo ...
- 王家林人工智能AI课程大纲和电子书 - 老师微信13928463918
**3980元团购原价19800元的AI课程,团购请加王家林老师微信13928463918. 基于王家林老师独创的人工智能"项目情景投射"学习法,任何IT人员皆可在无需数学和Pyt ...
- RDO Stack: Failed connect to server
Issue: When you create an instance, but cannot connect to the VNC Server because of the error messag ...
- Dynamics 365 你所期待的子网格编辑终于来了
Dynamics 365的online版本已经在11月1号发布了,on-premises版也在没几天后发布,今天略看了一眼 what's new 一眼就看到了 editable grids,这个不用我 ...
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...
- Bootstrap3 排版-地址
让联系信息以最接近日常使用的格式呈现.在每行结尾添加 可以保留需要的样式. Twitter, Inc. 795 Folsom Ave, Suite 600 San Francisco, CA 9410 ...
- WiFi文件上传框架SGWiFiUpload
背景 在iOS端由于文件系统的封闭性,文件的上传变得十分麻烦,一个比较好的解决方案是通过局域网WiFi来传输文件并存储到沙盒中. 简介 SGWiFiUpload是一个基于CocoaHTTPServer ...
- Linux下文件和文件夹操作命令详解
花了两个小时的时间,把文件和文件夹相关的常用命令:创建.删除.移动.复制.查找.重命名在linux上测试了一把,总结下来.文件夹的这些基本操作是要多注意的,一不小心就达不到你想要的效果. 文件夹操作: ...
- 物料分类新增&更新
--新增 INV_ITEM_CATEGORY_PUB.Create_Category ( p_api_version IN NUMBER, p_init_msg_list IN VARCHAR2 DE ...
- Java进阶(四十六)简述ArrayList、Vector与LinkedList的异同点
简述ArrayList.Vector与LinkedList的异同点 Collection类的继承图如下: 从图中可以看出,LinkedList与ArrayList.ArrayDeque这三者都 ...