亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2686 | 回復(fù): 0
打印 上一主題 下一主題

【探討】通過實(shí)例再討論TDD [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-02-28 17:06 |只看該作者 |倒序?yàn)g覽
在《測(cè)試驅(qū)動(dòng)開發(fā)》(Kent Beck)的附錄B,Kent Beck用了兩頁紙的篇幅,演示了一次完全以測(cè)試驅(qū)動(dòng)的方式,開發(fā)計(jì)算斐波納契數(shù)列。

先簡(jiǎn)短的抄一下代碼,再談?wù)勎业目捶ā?

第一個(gè)測(cè)試與第一次的代碼
  1. public void testFibonacci();
  2.     assertEquals(0,fib(0););;
  3. }

  4. int fib(int n);{
  5.     return 0;
  6. }
復(fù)制代碼
第二個(gè)測(cè)試與第二次的代碼
Java代碼
  1. public void testFibonacci();   
  2.     assertEquals(0,fib(0););;   
  3.     assertEquals(1,fib(1););;   
  4. }   
  5.   
  6. int fib(int n);{   
  7.     if(n==0); return 0;   
  8.     return 1;   
  9. }  

  10. public void testFibonacci();
  11.     assertEquals(0,fib(0););;
  12.     assertEquals(1,fib(1););;
  13. }

  14. int fib(int n);{
  15.     if(n==0); return 0;
  16.     return 1;
  17. }
復(fù)制代碼
對(duì)測(cè)試代碼進(jìn)行改進(jìn),使之更為通用
Java代碼
  1. public void testFibonacci();{   
  2.     int cases[][]={{0,0},{1,1}};   
  3.     for(int i=0;i<cases.length;i++);{   
  4.         assertEquals(cases[i][1],fib(cases[i][0]););;   
  5. }  

  6. public void testFibonacci();{
  7.     int cases[][]={{0,0},{1,1}};
  8.     for(int i=0;i<cases.length;i++);{
  9.         assertEquals(cases[i][1],fib(cases[i][0]););;
  10. }
復(fù)制代碼
再增加n=2的測(cè)試
Java代碼
  1. public void testFibonacci();{   
  2.     int cases[][]={{0,0},{1,1},{2,1}};   
  3.     for(int i=0;i<cases.length;i++);{   
  4.         assertEquals(cases[i][1],fib(cases[i][0]););;   
  5. }  

  6. public void testFibonacci();{
  7.     int cases[][]={{0,0},{1,1},{2,1}};
  8.     for(int i=0;i<cases.length;i++);{
  9.         assertEquals(cases[i][1],fib(cases[i][0]););;
  10. }
復(fù)制代碼
不需要修改代碼,測(cè)試就通過了。

再增加n=3的測(cè)試
Java代碼
  1. public void testFibonacci();{   
  2.     int cases[][]={{0,0},{1,1},{2,1},{3,2}};   
  3.     for(int i=0;i<cases.length;i++);{   
  4.         assertEquals(cases[i][1],fib(cases[i][0]););;   
  5. }  

  6. public void testFibonacci();{
  7.     int cases[][]={{0,0},{1,1},{2,1},{3,2}};
  8.     for(int i=0;i<cases.length;i++);{
  9.         assertEquals(cases[i][1],fib(cases[i][0]););;
  10. }
復(fù)制代碼
測(cè)試失敗,于是修改代碼,還是如法炮制
Java代碼
  1. int fib(int n);{   
  2.     if(n==0); return 0;   
  3.     if(n<=2); return 1;   
  4.     return 2;   
  5. }  

  6. int fib(int n);{
  7.     if(n==0); return 0;
  8.     if(n<=2); return 1;
  9.     return 2;
  10. }
復(fù)制代碼
然后,最為神奇的部分在下面的四次修改:

1:
Java代碼
  1. int fib(int n);{   
  2.     if(n==0); return 0;   
  3.     if(n<=2); return 1;   
  4.     return 1+1;//注意這里   
  5. }  

  6. int fib(int n);{
  7.     if(n==0); return 0;
  8.     if(n<=2); return 1;
  9.     return 1+1;//注意這里
  10. }
復(fù)制代碼
2:
Java代碼
  1. int fib(int n);{   
  2.     if(n==0); return 0;   
  3.     if(n<=2); return 1;   
  4.     return fib(n-1);+1;//注意這里   
  5. }  

  6. int fib(int n);{
  7.     if(n==0); return 0;
  8.     if(n<=2); return 1;
  9.     return fib(n-1);+1;//注意這里
  10. }
復(fù)制代碼
3:
Java代碼
  1. int fib(int n);{   
  2.     if(n==0); return 0;   
  3.     if(n<=2); return 1;   
  4.     return fib(n-1);+fib(n-2);;//注意這里   
  5. }  

  6. int fib(int n);{
  7.     if(n==0); return 0;
  8.     if(n<=2); return 1;
  9.     return fib(n-1);+fib(n-2);;//注意這里
  10. }
復(fù)制代碼
4:
Java代碼
  1. int fib(int n);{   
  2.     if(n==0); return 0;   
  3.     if(n==1); return 1;//注意這里   
  4.     return fib(n-1);+fib(n-1);;   
  5. }  

  6. int fib(int n);{
  7.     if(n==0); return 0;
  8.     if(n==1); return 1;//注意這里
  9.     return fib(n-1);+fib(n-1);;
  10. }
復(fù)制代碼
這是一個(gè)非常棒的過程。我們的討論也從這里開始。

最后得到的這個(gè)函數(shù),是一個(gè)遞歸函數(shù),非常的簡(jiǎn)潔,但是往往會(huì)有效率問題。

(打住,告訴過你多少次了,不要考慮效率!)

不是我要考慮效率,只是這么簡(jiǎn)單的例子,要尋找別的設(shè)計(jì)方式,我只能從效率方面來說事。

OK,繼續(xù)。假設(shè)我們要求9的斐波納契數(shù)列的值,那么,fib函數(shù)就會(huì)去計(jì)算fib(8 )+fib(7)。然后我們?cè)僬归_。
fib(9)=fib(8 )+fib(7)
fib(9)=(fib(7)+fib(6))+(fib(6)+fib(5))
注意,這里fib(6)就要被計(jì)算兩遍。
fib(9)=((fib(6)+fib(5))+(fib(5)+fib(4)))+((fib(5)+fib(4))+(fib(4)+fib(3)))
注意,這里fib(5)要被計(jì)算3遍,fib(4)要被計(jì)算3遍。


理解我的意思了嗎?這樣的算法,存在嚴(yán)重的效率隱患。
如果我們要考慮效率,會(huì)如何寫代碼呢?
Java代碼
  1. public int fib(int n);{   
  2.     int value0=0;   
  3.     int value1=0;   
  4.     int value=0;   
  5.     for(int i=0;i<=n;i++);{   
  6.         if(i==1);{   
  7.             value1=1;   
  8.             value=1;   
  9.         } else {   
  10.             value=value0+value1;   
  11.             value0=value1;   
  12.             value1=value;   
  13.         }   
  14.     }   
  15.     return value;   
  16. }  

  17. public int fib(int n);{
  18.     int value0=0;
  19.     int value1=0;
  20.     int value=0;
  21.     for(int i=0;i<=n;i++);{
  22.         if(i==1);{
  23.             value1=1;
  24.             value=1;
  25.         } else {
  26.             value=value0+value1;
  27.             value0=value1;
  28.             value1=value;
  29.         }
  30.     }
  31.     return value;
  32. }
復(fù)制代碼
這個(gè)算法我就不解釋了。有人也許會(huì)說,你這樣不是TDD,你先寫了程序!

不要緊,我可以假裝先寫了測(cè)試代碼
Java代碼
  1. public void testFibonacci();{   
  2.     int cases[][]={{0,0},{1,1},{2,1},{3,2}};   
  3.     for(int i=0;i<cases.length;i++);{   
  4.         assertEquals(cases[i][1],fib(cases[i][0]););;   
  5. }  

  6. public void testFibonacci();{
  7.     int cases[][]={{0,0},{1,1},{2,1},{3,2}};
  8.     for(int i=0;i<cases.length;i++);{
  9.         assertEquals(cases[i][1],fib(cases[i][0]););;
  10. }
復(fù)制代碼
然后再把剛才的那個(gè)程序?qū)懗鰜,這樣有什么問題嗎?這樣還算是TDD嗎?

我仔細(xì)看了書了,Kent Beck說過“步伐”問題。我這樣也可以算是TDD的,只是步子大了點(diǎn)。

那么我想說明什么問題呢?
1、無論先寫測(cè)試還是先寫代碼,都需要考慮設(shè)計(jì)問題
2、在寫測(cè)試之前考慮設(shè)計(jì)問題,不是什么罪過
3、考慮設(shè)計(jì)思路的深入與否,決定了步伐的大小
4、步伐太小的設(shè)計(jì)考慮,可能會(huì)陷入死角,無法再優(yōu)化下去。從上面的代碼可以看到,要想使遞歸算法變成循環(huán)算法,不是重構(gòu)能夠做到的。


最終的結(jié)論是:
代碼就像你的左腳,測(cè)試就像你的右腳。
你可以先邁左腳,再邁右腳。然后一直走下去。
也可以先邁右腳,再邁左腳。然后一直走下去。
只要你不是一直單腳跳著前進(jìn),你都會(huì)走得很穩(wěn),而且沒有人看得出區(qū)別來。


原文http://www.javaeye.com/topic/6551
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP