<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jaunty@软件测试，音乐，还有不一样的生活 &#187; 软件设计开发</title>
	<atom:link href="http://jaunty.me/blog/category/%e8%bd%af%e4%bb%b6%e8%ae%be%e8%ae%a1%e5%bc%80%e5%8f%91/feed/" rel="self" type="application/rss+xml" />
	<link>http://jaunty.me/blog</link>
	<description>软件测试，自动化测试，QTP，Loadrunner，Java，软件开发，性能测试，开源</description>
	<lastBuildDate>Tue, 24 Aug 2010 03:40:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>个人拙见-阿Q版TDD~BDD是也。</title>
		<link>http://jaunty.me/blog/2009/01/bdd-is-consolation-of-td/</link>
		<comments>http://jaunty.me/blog/2009/01/bdd-is-consolation-of-td/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 03:03:49 +0000</pubDate>
		<dc:creator>jaunty</dc:creator>
				<category><![CDATA[Agile敏捷]]></category>
		<category><![CDATA[单元测试]]></category>
		<category><![CDATA[软件设计开发]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[敏捷开发]]></category>

		<guid isPermaLink="false">http://jaunty.me/blog/?p=61</guid>
		<description><![CDATA[今天csdn推出java工具大总结，看到BDD的概念已经逐渐成为流行。之前有段时间关注敏捷和TDD，对BDD有个浅显的接触，当然仅限于名称的了解。既然成为流行，当然要深究一下。
BDD（behavior driven development）行为驱动开发。敏捷开发的一种方式。
维基的解释http://en.wikipedia.org/wiki/Behavior_Driven_Development
 大概BDD 就是个基于行为的设计方法。其实TDD应该也可以算是设计方法吧。不过他们各自的关注点不一样。
例如TDD可能比较贴近功能点，而BDD以我拙劣的理解能力看来，就是换了个yy方式吧，可能是为了让开发能够从测试的怪圈里跳出来，从而只关注这段程序应该做什么，要做什么。而不是关注在这个数组边界是多少，数组类型是什么，从而写对应的单元测试以保证这些功能点，业务规则，甚至是程序规范这些细致的点。

从下面这篇文章看来
http://www.ibm.com/developerworks/cn/java/j-cq09187/
其实BDD的代码也是非常有特色的 不再是Test开头都变成Should开头了。呵呵。个人感觉，这样一种行为驱动，似乎就是将需求细分成很多功能和系统行为，边设计边开发。写的稍微粗点的话，这又和敏捷的userstory有什么区别呢？
然而userstory 其实又可以说是用户的简单的需求卡。那么这样追溯下去其实就是拿着一个有条理的需求边设计边开发而已。
可能框架提供了很好的环境和接口。由于我没有实践和经历过BDD，单从此时有的材料纸上谈兵一下，感觉上似乎BDD的结果就是测试保证了功能点的功能结果。无形加重后期测试成本。但是TDD，如果测试设计的好可以在单元测试过程中覆盖到很多程序员一些不良习惯，粗心大意造成的问题。。
就这样原始追求发展，发展后有复古回归原始。有点像7，80年代流行喇叭裤，8，90年代流行窄脚裤，直筒，90年代末到21世纪初又开始流行喇叭裤，现在2008，2009年了又介于喇叭裤和窄脚裤的过渡期间。
感觉上这BDD有点像行为艺术，哈哈。
其他的一些参考：
http://www.javaeye.com/problems/2221
http://tech.it168.com/d/2008-03-10/200803101401922.shtml
http://www.infoq.com/cn/news/2008/02/unit_tests_forests_n_trees
]]></description>
			<content:encoded><![CDATA[<p>今天csdn推出java工具大总结，看到BDD的概念已经逐渐成为流行。之前有段时间关注敏捷和TDD，对BDD有个浅显的接触，当然仅限于名称的了解。既然成为流行，当然要深究一下。</p>
<p>BDD（behavior driven development）行为驱动开发。敏捷开发的一种方式。</p>
<p>维基的解释<a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">http://en.wikipedia.org/wiki/Behavior_Driven_Development</a></p>
<p> 大概BDD 就是个基于行为的设计方法。其实TDD应该也可以算是设计方法吧。不过他们各自的关注点不一样。</p>
<p>例如TDD可能比较贴近功能点，而BDD以我拙劣的理解能力看来，就是换了个yy方式吧，可能是为了让开发能够从测试的怪圈里跳出来，从而只关注这段程序应该做什么，要做什么。而不是关注在这个数组边界是多少，数组类型是什么，从而写对应的单元测试以保证这些功能点，业务规则，甚至是程序规范这些细致的点。</p>
<p><span id="more-61"></span></p>
<p>从下面这篇文章看来</p>
<p><a href="http://www.ibm.com/developerworks/cn/java/j-cq09187/">http://www.ibm.com/developerworks/cn/java/j-cq09187/</a></p>
<p>其实BDD的代码也是非常有特色的 不再是Test开头都变成Should开头了。呵呵。个人感觉，这样一种行为驱动，似乎就是将需求细分成很多功能和系统行为，边设计边开发。写的稍微粗点的话，这又和敏捷的userstory有什么区别呢？</p>
<p>然而userstory 其实又可以说是用户的简单的需求卡。那么这样追溯下去其实就是拿着一个有条理的需求边设计边开发而已。</p>
<p>可能框架提供了很好的环境和接口。由于我没有实践和经历过BDD，单从此时有的材料纸上谈兵一下，感觉上似乎BDD的结果就是测试保证了功能点的功能结果。无形加重后期测试成本。但是TDD，如果测试设计的好可以在单元测试过程中覆盖到很多程序员一些不良习惯，粗心大意造成的问题。。</p>
<p>就这样原始追求发展，发展后有复古回归原始。有点像7，80年代流行喇叭裤，8，90年代流行窄脚裤，直筒，90年代末到21世纪初又开始流行喇叭裤，现在2008，2009年了又介于喇叭裤和窄脚裤的过渡期间。</p>
<p>感觉上这BDD有点像行为艺术，哈哈。</p>
<p>其他的一些参考：</p>
<p><a href="http://www.javaeye.com/problems/2221">http://www.javaeye.com/problems/2221</a></p>
<p><a href="http://tech.it168.com/d/2008-03-10/200803101401922.shtml">http://tech.it168.com/d/2008-03-10/200803101401922.shtml</a></p>
<p><a href="http://www.infoq.com/cn/news/2008/02/unit_tests_forests_n_trees">http://www.infoq.com/cn/news/2008/02/unit_tests_forests_n_trees</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jaunty.me/blog/2009/01/bdd-is-consolation-of-td/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[转]当下10大最热门的网站开发技术</title>
		<link>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%bd%93%e4%b8%8b10%e5%a4%a7%e6%9c%80%e7%83%ad%e9%97%a8%e7%9a%84%e7%bd%91%e7%ab%99%e5%bc%80%e5%8f%91%e6%8a%80%e6%9c%af/</link>
		<comments>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%bd%93%e4%b8%8b10%e5%a4%a7%e6%9c%80%e7%83%ad%e9%97%a8%e7%9a%84%e7%bd%91%e7%ab%99%e5%bc%80%e5%8f%91%e6%8a%80%e6%9c%af/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 01:50:49 +0000</pubDate>
		<dc:creator>jaunty</dc:creator>
				<category><![CDATA[职业发展]]></category>
		<category><![CDATA[软件设计开发]]></category>
		<category><![CDATA[开发，程序设计]]></category>
		<category><![CDATA[网站开发]]></category>

		<guid isPermaLink="false">http://jaunty.me/blog/?p=30</guid>
		<description><![CDATA[ 虽然现在美国经济出现危机，但是网站开发领域依然很繁荣，因为不论是现在或者将来，网络必定是人们日常生活中不可缺少的组成部分。NETTUTS上列出10大最吃香的网站开发技术。作为网站开发工程师，如果你精通这些技术，即便在经济不景气的时候，仍然很容易找到一份好工作。
1. Framework knowledge (架构知识)
    架构是大型网站开发的重要部分。开发者已经从Rails, Django等公司提供的网站架构工具中收益，因为架构工具可以帮助完成那些需要一定编程知识的重复性的任务。如果你拥有领先的架构技术(像Rails, Django, CakePHP, Symfony等)，你的择业面将非常广阔。

2. Widget Development (窗体小部件开发)
　窗体小部件(Widgets)是一个嵌入网页的迷你应用程序，通常也可以下载到Windows或者Mac桌面下运行。它让数据变得便与携带而且更具交互性。比较出名的像Yahoo Widgets和AOL Music Widgets。窗体小部件开发除了需要掌握网络应用程序开发所需的语言知识，还需要精通Javascript和Flash知识。
3. Custom CMS themes (内容管理系统主题定制)
　如今越来越多人开始使用CMS(内容管理系统，例如Wordpress和Drupal)来构建他们的网站。可以想象不可能大家都用CMS提供的默认主题，为了让自己的CMS网站在外观设计上独树一帜，就需要一些专门给CMS开发主题的技术人员。
4. CMS Customizations and plugin development (内容管理系统的定制以及插件开发)
　同样随着CMS的流行，对CMS的功能定制以及插件开发的需求也越来越大。
5. PSD to XHTML services (PSD转换XHTML的服务）
　在建站中，许多公司是先用Photoshop设计好网站的外观原图，然后再转换成XHTML。这需要很强的CSS/HTML知识。
6. Javascript Plugin creation(Javascript的插件开发)
　Javascript的Framework非常流行，因为它使Javascript的代码开发变得简单。就比如说现在流行的Javascript Framework &#8211; jQuery，如果你在它的基础上开发优秀的插件，那么你的插件也会跟着流行起来。
7. Facebook/MySpace applications (Facebook/MySpace 应用程序开发)
　Facebook/MySpace两大社交网站在美国红遍半边天。给他们开发应用程序，不用说一定是相当热门的。
8. iPhoneapplications (iPhone 应用程序开发)
　同样给iPhone开发应用程序，也一直都可以被大量下载，因此也是很赚钱的活。
9. E-commerce integration (电子商务一体化)
　如今电子商务网站(像Ebay，Amazon)与在线银行服务系统(像Paypal和Google Checkout的)之间的配合越来越紧密，因此电子商务交易平台的开发也是相当有前途的。
10. Flash and Actionscript Knowledge [...]]]></description>
			<content:encoded><![CDATA[<p> 虽然现在美国经济出现危机，但是网站开发领域依然很繁荣，因为不论是现在或者将来，网络必定是人们日常生活中不可缺少的组成部分。NETTUTS上列出10大最吃香的网站开发技术。作为网站开发工程师，如果你精通这些技术，即便在经济不景气的时候，仍然很容易找到一份好工作。</p>
<p>1. Framework knowledge (架构知识)</p>
<p>    架构是大型网站开发的重要部分。开发者已经从Rails, Django等公司提供的网站架构工具中收益，因为架构工具可以帮助完成那些需要一定编程知识的重复性的任务。如果你拥有领先的架构技术(像Rails, Django, CakePHP, Symfony等)，你的择业面将非常广阔。</p>
<p><span id="more-30"></span><br />
2. Widget Development (窗体小部件开发)</p>
<p>　窗体小部件(Widgets)是一个嵌入网页的迷你应用程序，通常也可以下载到Windows或者Mac桌面下运行。它让数据变得便与携带而且更具交互性。比较出名的像Yahoo Widgets和AOL Music Widgets。窗体小部件开发除了需要掌握网络应用程序开发所需的语言知识，还需要精通Javascript和Flash知识。</p>
<p>3. Custom CMS themes (内容管理系统主题定制)</p>
<p>　如今越来越多人开始使用CMS(内容管理系统，例如Wordpress和Drupal)来构建他们的网站。可以想象不可能大家都用CMS提供的默认主题，为了让自己的CMS网站在外观设计上独树一帜，就需要一些专门给CMS开发主题的技术人员。</p>
<p>4. CMS Customizations and plugin development (内容管理系统的定制以及插件开发)</p>
<p>　同样随着CMS的流行，对CMS的功能定制以及插件开发的需求也越来越大。</p>
<p>5. PSD to XHTML services (PSD转换XHTML的服务）</p>
<p>　在建站中，许多公司是先用Photoshop设计好网站的外观原图，然后再转换成XHTML。这需要很强的CSS/HTML知识。</p>
<p>6. Javascript Plugin creation(Javascript的插件开发)</p>
<p>　Javascript的Framework非常流行，因为它使Javascript的代码开发变得简单。就比如说现在流行的Javascript Framework &#8211; jQuery，如果你在它的基础上开发优秀的插件，那么你的插件也会跟着流行起来。</p>
<p>7. Facebook/MySpace applications (Facebook/MySpace 应用程序开发)</p>
<p>　Facebook/MySpace两大社交网站在美国红遍半边天。给他们开发应用程序，不用说一定是相当热门的。</p>
<p>8. iPhoneapplications (iPhone 应用程序开发)</p>
<p>　同样给iPhone开发应用程序，也一直都可以被大量下载，因此也是很赚钱的活。</p>
<p>9. E-commerce integration (电子商务一体化)</p>
<p>　如今电子商务网站(像Ebay，Amazon)与在线银行服务系统(像Paypal和Google Checkout的)之间的配合越来越紧密，因此电子商务交易平台的开发也是相当有前途的。</p>
<p>10. Flash and Actionscript Knowledge (Flash和Actionscript知识)</p>
<p>　越来越多的公司采用Flash来制作自己的网站、展现自己的产品，因为精美的动画总是容易吸引人们的眼球。因此Flash动画技术也必然迅速发展。</p>
]]></content:encoded>
			<wfw:commentRss>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%bd%93%e4%b8%8b10%e5%a4%a7%e6%9c%80%e7%83%ad%e9%97%a8%e7%9a%84%e7%bd%91%e7%ab%99%e5%bc%80%e5%8f%91%e6%8a%80%e6%9c%af/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]写出漂亮代码的七种方法</title>
		<link>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%86%99%e5%87%ba%e6%bc%82%e4%ba%ae%e4%bb%a3%e7%a0%81%e7%9a%84%e4%b8%83%e7%a7%8d%e6%96%b9%e6%b3%95/</link>
		<comments>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%86%99%e5%87%ba%e6%bc%82%e4%ba%ae%e4%bb%a3%e7%a0%81%e7%9a%84%e4%b8%83%e7%a7%8d%e6%96%b9%e6%b3%95/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 01:43:57 +0000</pubDate>
		<dc:creator>jaunty</dc:creator>
				<category><![CDATA[软件设计开发]]></category>
		<category><![CDATA[开发，程序设计]]></category>

		<guid isPermaLink="false">http://jaunty.me/blog/?p=16</guid>
		<description><![CDATA[首先我想说明我本文阐述的是纯粹从美学的角度来写出代码，而非技术、逻辑等。以下为写出漂亮代码的七种方法：
1， 尽快结束 if语句
例如下面这个JavaScript语句，看起来就很恐怖：
1 function findShape(flags, point, attribute, list) {
2    if(!findShapePoints(flags, point, attribute)) {
3        if(!doFindShapePoints(flags, point, attribute)) {
4            if(!findInShape(flags, point, attribute)) {
5                if(!findFromGuide(flags,point) {
6                    if(list.count() &#62; 0 &#38;&#38; flags == 1) {
7                          doSomething();
8                    }
9                }
10            }
11       }
12    } 
13  }
 
阅读全文…
但如果这么写就好看得多：
1 function findShape(flags, point, attribute, list) {
2    if(findShapePoints(flags, point, attribute)) {
3        return;
4    }
5
6    if(doFindShapePoints(flags, point, attribute)) {
7        return;
8    [...]]]></description>
			<content:encoded><![CDATA[<p>首先我想说明我本文阐述的是纯粹从美学的角度来写出代码，而非技术、逻辑等。以下为写出漂亮代码的七种方法：</p>
<p>1， 尽快结束 if语句</p>
<p>例如下面这个JavaScript语句，看起来就很恐怖：</p>
<p>1 function findShape(flags, point, attribute, list) {<br />
2    if(!findShapePoints(flags, point, attribute)) {<br />
3        if(!doFindShapePoints(flags, point, attribute)) {<br />
4            if(!findInShape(flags, point, attribute)) {<br />
5                if(!findFromGuide(flags,point) {<br />
6                    if(list.count() &gt; 0 &amp;&amp; flags == 1) {<br />
7                          doSomething();<br />
8                    }<br />
9                }<br />
10            }<br />
11       }<br />
12    } <br />
13  }</p>
<p> <span id="more-16"></span></p>
<p><a href="”&lt;?php"><strong>阅读全文…</strong></a></p>
<p>但如果这么写就好看得多：<br />
1 function findShape(flags, point, attribute, list) {<br />
2    if(findShapePoints(flags, point, attribute)) {<br />
3        return;<br />
4    }<br />
5<br />
6    if(doFindShapePoints(flags, point, attribute)) {<br />
7        return;<br />
8    }<br />
9<br />
10    if(findInShape(flags, point, attribute)) {<br />
11        return;<br />
12    }<br />
13<br />
14    if(findFromGuide(flags,point) {<br />
15        return;<br />
16    }<br />
17<br />
18    if (!(list.count() &gt; 0 &amp;&amp; flags == 1)) {<br />
19        return;<br />
20    }<br />
21<br />
22    doSomething();<br />
23<br />
24 }</p>
<p>你可能会很不喜欢第二种的表述方式，但反映出了迅速返回if值的思想，也可以理解为：避免不必要的else陈述。</p>
<p>2， 如果只是简单的布尔运算（逻辑运算），不要使用if语句</p>
<p>例如：<br />
1 function isStringEmpty(str){<br />
2    if(str === “”) {<br />
3        return true;<br />
4    }<br />
5    else {<br />
6        return false;<br />
7    }<br />
8 }</p>
<p>可以写为：<br />
1 function isStringEmpty(str){<br />
2    return (str === “”);<br />
3 }</p>
<p>3， 使用空白，这是免费的<br />
例如：<br />
1 function getSomeAngle() {<br />
2    // Some code here then<br />
3    radAngle1 = Math.atan(slope(center, point1));<br />
4    radAngle2 = Math.atan(slope(center, point2));<br />
5    firstAngle = getStartAngle(radAngle1, point1, center);<br />
6    secondAngle = getStartAngle(radAngle2, point2, center);<br />
7    radAngle1 = degreesToRadians(firstAngle);<br />
8    radAngle2 = degreesToRadians(secondAngle);<br />
9    baseRadius = distance(point, center);<br />
10    radius = baseRadius + (lines * y);<br />
11    p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);<br />
12    p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);<br />
13    pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);<br />
14    pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");<br />
15    // Now some more code<br />
16 }</p>
<p>很多开发者不愿意使用空白，就好像这要收费一样。我在此并非刻意地添加空白，粗鲁地打断代码的连贯性。在实际编写代码的过程中，会很容易地发现在什么地方加入空白，这不但美观而且让读者易懂，如下：<br />
1 function getSomeAngle() {<br />
2    // Some code here then<br />
3    radAngle1 = Math.atan(slope(center, point1));<br />
4    radAngle2 = Math.atan(slope(center, point2));<br />
5<br />
6    firstAngle = getStartAngle(radAngle1, point1, center);<br />
7    secondAngle = getStartAngle(radAngle2, point2, center);<br />
8<br />
9    radAngle1 = degreesToRadians(firstAngle);<br />
10    radAngle2 = degreesToRadians(secondAngle);<br />
11<br />
12    baseRadius = distance(point, center);<br />
13    radius = baseRadius + (lines * y);<br />
14<br />
15    p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);<br />
16    p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);<br />
17<br />
18    pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);<br />
19    pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");<br />
20    // Now some more code<br />
21 }</p>
<p>4， 不要使用无谓的注释<br />
无谓的注释让人费神，这实在很讨厌。不要标出很明显的注释。在以下的例子中，每个人都知道代码表达的是“students id”，因而没必要标出。<br />
1 function existsStudent(id, list) {<br />
2    for(i = 0; i &lt; list.length; i++) {<br />
3       student = list[i];<br />
4<br />
5       // Get the student’s id<br />
6       thisId = student.getId();<br />
7<br />
8       if(thisId === id) {<br />
9           return true;<br />
10       }<br />
11    }<br />
12    return false; <br />
13 }</p>
<p>5， 不要在源文件中留下已经删除的代码，哪怕你标注了<br />
如果你使用了版本控制，那么你就可以轻松地找回前一个版本的代码。如果别人大费周折地读了你的代码,却发现是要删除的代码，这实在太恨人了。</p>
<p>//function thisReallyHandyFunction() {<br />
//      someMagic();<br />
//      someMoreMagic();<br />
//      magicNumber = evenMoreMagic();<br />
//      return magicNumber;<br />
//}</p>
<p>6，不要有太长的代码</p>
<p>看太长的代码实在太费劲，尤其是代码本身的功能又很小。如下：</p>
<p>1 public static EnumMap&lt;Category, IntPair&gt; getGroupCategoryDistribution(EnumMap&lt;Category, Integer&gt; sizes, int groups) {<br />
2        EnumMap&lt;Category, IntPair&gt; categoryGroupCounts = new EnumMap&lt;Category,IntPair&gt;(Category.class);<br />
3<br />
4        for(Category cat : Category.values()) {<br />
5            categoryGroupCounts.put(cat, getCategoryDistribution(sizes.get(cat), groups));<br />
6        }</p>
<p>#</p>
<p>我并不是说非要坚持70个字符以内，但是一个比较理想的长度是控制在120个字符内。如果你把代码发布在互联网上，用户读起来就很困难。<br />
7，不要在一个功能（或者函数内）有太多代码行<br />
我的一个老同事曾经说Visual C++很臭，因为它不允许你在一个函数内拥有超过10，000行代码。我记不清代码行数的上限，不知道他说的是否正确，但我很不赞成他的观点。如果一个函数超过了50行，看起来有多费劲你知道么，还有没完没了的if循环，而且你还的滚动鼠标前后对照这段代码。对我而言，超过35行的代码理解起来就很困难了。我的建议是超过这个数字就把一个函数代码分割成两个。</p>
]]></content:encoded>
			<wfw:commentRss>http://jaunty.me/blog/2008/12/%e8%bd%ac%e5%86%99%e5%87%ba%e6%bc%82%e4%ba%ae%e4%bb%a3%e7%a0%81%e7%9a%84%e4%b8%83%e7%a7%8d%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[转]TDD，测试代码可以代替文档吗？</title>
		<link>http://jaunty.me/blog/2008/12/%e8%bd%actdd%ef%bc%8c%e6%b5%8b%e8%af%95%e4%bb%a3%e7%a0%81%e5%8f%af%e4%bb%a5%e4%bb%a3%e6%9b%bf%e6%96%87%e6%a1%a3%e5%90%97%ef%bc%9f/</link>
		<comments>http://jaunty.me/blog/2008/12/%e8%bd%actdd%ef%bc%8c%e6%b5%8b%e8%af%95%e4%bb%a3%e7%a0%81%e5%8f%af%e4%bb%a5%e4%bb%a3%e6%9b%bf%e6%96%87%e6%a1%a3%e5%90%97%ef%bc%9f/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 06:36:56 +0000</pubDate>
		<dc:creator>jaunty</dc:creator>
				<category><![CDATA[软件设计开发]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[软件设计]]></category>

		<guid isPermaLink="false">http://jaunty.me/blog/?p=8</guid>
		<description><![CDATA[TDD，测试代码可以代替文档吗]]></description>
			<content:encoded><![CDATA[<p>曾经，我认为只要做好详细设计工作，软件编码就成为一种体力活。在我印象中传统软件工程理论好像是这么说得：分析和设计是软件生产过程中最重要的两个阶段，好的设计产生好的结果，坏的设计产生坏的结果，详细设计文档是软件过程中最重要的部分，甚至比代码还重要。国内某人的书中还提到，“只要有了详细设计，哪怕原来的开发人员都离开了，换一批人照着详细设计仍然能把软件做完”。一提到详细设计我的脑子里也已经出现了这样的影子：长长的（或者厚厚的）文档，详细到每个函数，甚至是每个函数参数的名字都定义好了，用这样的详细设计指导代码编写应该是一件多么惬意的事情啊。我推崇这种事无巨细的详细设计，认为只要是设计好就能够适应变化，并把软件项目的失败归咎与设计人员的知识、能力或经验不足。这种想法持续了很长时间，直到我有了实际软件项目的经验并开始单独做设计为止。<br />
<span id="more-8"></span><br />
    促使我思想转变的原因就是两个字：变化。我原来也知道变化对设计的影响，但是还是低估了变化对设计带来的冲击。现实中的详细设计只是一个看上去很美的东西，开始编写代码一个月后的详细设计就基本上不能指导代码编写了，甚至变成和实际代码完全两回事的东西，成了一堆废纸，原因还是那两个字：变化。是的，变化，在某个时间已经很缜密的设计，在下个时间就会变得漏洞百出，因为计划赶不上变化，通常情况下，详细设计文档从其完成的那一刻起就开始散发出“腐败”的味道。只有没有任何软件开发经验的人才会天真地认为一次做好完备的详细设计，然后就可以在其指导下完成软件开发，最终得到产品。</p>
<p>    在传统的软件过程中，面对逐渐散发出“腐败”味道的设计文档，通常有两种对策，一种是安排专职的文档开发人员，每次在代码中修改设计都及时更新到设计文档中，以保持文档的“新鲜”。其实这种方法也只是一种看上去很美的东西，且不说多数项目组都不会有多余的人手专职做文档开发（有哪个项目组敢在项目还在进行中就说自己的人手足够了？），就算有这样一个文档开发人员，那么是否每次设计上的小修改都会通知到他（她）呢？显然不会，他（她）必须Review每一个开发人员的代码，并与大家随时沟通，发现与原始设计不一致的修改，这样会累死人的。那么是否可以由开发人员自己负责维护与自己工作相关的那部分文档呢？试想一下，当轰轰烈烈地代码编写开始后，或者头顶着产品交付倒计时牌，开发人员是否还有“闲情逸致”时不时停下正在Coding的手去重新修改一下设计文档呢？另一种对策是任由设计文档慢慢“腐败”，把主要力量集中在代码上，毕竟最终交付产品依靠代码而不是设计文档。这种情况下原来花费大量时间完成设计文档纯粹是浪费时间，哪怕是对自己人也没有丝毫用处，如果我是这个项目组中补充进来的新人，看到这样的文档和那样的代码，可能会得精神分裂症。</p>
<p>    所以在敏捷（Agile）的词汇表里已经没有详细设计这个词汇了，取而代之的是“够用设计”，就是所谓的Not less not more， just enough。那么在敏捷这种短迭代周期，快速反馈体系中，是否还有必要编写一份用自然语言或图表展示的详细设计文档呢？Jack W.Reecves在他的论文《什么是软件设计？》中提出了“源代码就是设计文档”的观点，Jack说得设计文档和我本文提到的设计文档还不是同一个概念，我把他的观点引用在这里主要是为了和另一个观点做对比。Jack认为，“任何工程活动的最终目标都是某些类型的文档。当设计工作完成时，设计文档就被转交给制造团队。该团队是一个和设计团队完全不同的群体，并且其技能也和设计团队完全不同”【1】，由此看来，如果源代码不是文档，那么软件开发人员就不能被称为是工程师了，他们就和建筑工地上的工人一样，只是一群Builder。是否可以用源代码代替任何用自然语言描述的文档呢？我看还不太可行，源代码相对于自然语言来说过于晦涩，只有开发人员能够读懂（即便是开发人员，也不是所有人都能理解所有代码），显然制约了源代码作为文档的用途。不是有人在研究用自然语言编程序吗，如果这样的类似自然语言的源代码作为文档，倒是很合适。</p>
<p>    上文提到，有一个与之对比的观点，那就是用测试代码代替源代码作为设计文档，但是前提条件是：使用TDD作为开发模式。很显然，源代码产生以后做单元测试用的测试代码已经失去了作为设计文档的前提，那就是每次迭代的设计文档必须早于或不晚于本次迭代的源代码产生出来。因为作为单元测试的测试代码是为已经存在的源代码量身定做的，并且已经受到这些代码的思维定势影响，失去了“设计”的意义。做为测试先行的TDD本身就是一个分析、设计、实现的过程，而测试代码又是这个过程的产物，测试代码理所当然的就是设计文档了。加之TDD要求在编写任何代码之前要先完成测试用例，这就是说任何新代码（新加的模块）都有配套的测试代码，自然而然的，测试代码就成为了新代码的描述文档，其中包含了如何建立使用新模块以及期望达到什么样的效果，而这正式设计文档的主要功能。源代码不适合取代自然语言的文档，因为源代码过于功能细化，逻辑纷繁复杂，分支和跳转加剧了理解代码的困难，缺乏对整个模块的宏观表达能力。与源代码相比，测试代码显然“单纯”很多，测试代码侧重于使用源代码，通常可以用作源代码的一份sample，所以它对整个模块的宏观表达能力要强于源代码。另外，测试代码通常是线性结构，比较容易看懂，从可理解性上看，测试代码比源代码更接近自然语言，因此测试代码比源代码更适合作为软件的设计文档。<br />
    </p>
<p>    那么测试代码是否可以完全取代自然语言形式的设计文档呢？我看还不行，原因有三：<br />
其一，测试代码虽然比源代码容易理解，但它仍然是代码，不是所有人都能理解的；<br />
其二，测试代码的宏观表达能力还是不如自然语言或图表；<br />
其三，很多人习惯看文字而不是看代码，彻底改变人的习惯很难。<br />
所以在TDD开发过程中，比较好的形式是自然语言的文档和测试代码相结合，用自然语言的文档做一个够用的设计就行了，这个设计只要详细到模块关系这一级别就足够了，各个模块的详细设计就由测试代码充当。</p>
<p>    不管是“源代码就是文档”的观点还是“测试代码就是文档”的观点，目的都只有一个，那就是消除那些浪费人力物力做出来的、没用的、总是散发着“腐败”味道的东西。</p>
<p>[1] Jack W.Reecves. 什么是软件设计. 2002.</p>
]]></content:encoded>
			<wfw:commentRss>http://jaunty.me/blog/2008/12/%e8%bd%actdd%ef%bc%8c%e6%b5%8b%e8%af%95%e4%bb%a3%e7%a0%81%e5%8f%af%e4%bb%a5%e4%bb%a3%e6%9b%bf%e6%96%87%e6%a1%a3%e5%90%97%ef%bc%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
