天天看點

靈活開發“松結對程式設計”系列之十二:L型代碼結構(品質篇之一)

有沒有一種管理方法,無需額外的測試活動,就能大幅度提高産品品質?L型代碼結構就是其中一種候選方案。

要減少缺陷,就要先弄清楚到底缺陷是從哪裡來的?就我自己的經驗而言,大概20%的新手,制造了系統中50%以上的缺陷;而若将人群擴大到80%的新手+中等水準的人,估計他們能制造95%的缺陷;而剩下的20%的高手,可能隻制造了5%的缺陷,甚至更低。

這種情況,甚至在高手主動承擔最艱巨的部分任務的時候,也是如此。實際上缺陷主要來自于程式設計者的程式設計素養,這使得及時團隊中即使有一些高手可以做到接近0缺陷,但隻要有新手在,程式一樣Bug亂飛。

若所有隊員各自負責一個或一些功能,每個人都從上層頁面、中間的業務邏輯、底層的資料通路一直做下來而互不溝通,代碼中缺陷會如何分布呢?

典型的情況,是高手負責的那個子產品從上到下都沒什麼問題,但這不能阻止别人的代碼經常出問題,是以整個産品的品質不會很好。

在某些缺少管理的團隊中,這種開發模式很常見;但在某些靈活開發團隊中,人們也常常采用這種方式,即人們各自“主動領取”任務,然後獨立完成其所有分析、編碼、測試工作,然後送出任務。

若所有隊員按層次(一般是表現層View、業務邏輯層Model、資料通路層Data,如果是MVC模式,還有控制層Controller)開發,又會如何呢?

這個模型我所在的團隊多次用過,品質明顯優于縱向分工的“川”型代碼結構。之前多次提到的那個23開發+2測試的團隊,開始就是用的“三”型代碼結構。

這個模型提高品質的原理是:若将被反複通路的Model和Data等底層代碼交給高手完成,則這些代碼中本身的缺陷就會很少;由于“反複使用”相同代碼,一處發現缺陷,其他處的缺陷也被同時修改,缺陷的修複成本很低;而未來新開發的功能,再次調用這些代碼時,則可以直接享受到接近零成本、零缺陷的效果。

三型代碼結構的品質問題主要在業務,即即使子產品級别的缺陷不再變得很明顯,但業務邏輯的錯誤往往仍然存在,代碼準确無誤地互相調用,但最終形成一個錯誤的邏輯結果。這一點在高手們都在忙于設計高度複用的底層子產品,而相對的新手進行業務開發的時候尤其明顯。當年的2個測試人員,也是為了解決業務測試才聘用的。

三型代碼結構的另外一個問題是“需求鍍金”。由于多數底層代碼都要先于上層代碼出現,是以經常有過度設計的情況。當年我做的第一個底層庫,就差不多有50%的功能沒有實際被用到;盡管這一情況後來得到了改善,但由于很難預測哪些有用哪些沒用,鍍金問題一直存在。鍍金問題雖然一般不會導緻災難性後果,但若高手們50%的時間在鍍金,生産力的浪費也是很嚴重的,工作效率大打折扣。

在我自己的經曆中,L型代碼是由川代碼演化而來的。

我發現若有一新一老兩個程式員分工,獨立完成各自的代碼。則一般出現以下現象:

1. 新程式員完成的功能少;老程式員完成的功能多。

2. 新程式員傾向于把代碼不分層次地編寫成一個大塊;若需要自己複用,則可以拷貝粘貼。

3. 老程式員傾向于把代碼分層次;盡管隻有他自己會複用,但仍會主動提煉類和函數。

4. 盡管兩者從不溝通,老程式員的可複用類卻可能覆寫新程式員的絕大多數需求,包括絕大多數的資料通路Data級别的代碼,以及一些底層業務邏輯代碼Model和界面代碼View。

比如若一個人開發“産品管理”子產品,要管理“産品線-産品-版本-釋出”等層次;而另外一個人在開發“部門管理”,要管理“公司-分公司-部門-團隊-小組”等層次,除了顯而易見的資料庫通路代碼、緩存等可以互相複用外,樹形結構的業務代碼也可以複用,而顯示他們的界面甚至都可以複用。

若老程式員已經開發了這些可複用代碼,新程式員就可以直接使用他們。

5. 老程式員不會發生太多的“鍍金”現象。

原因何在?因為他沒有“專職地”開發底層庫,而是根據自己的需要開發了底層庫。我們自己的資料(沒有仔細度量)是,我們的11000行代碼中,大約有2000多個函數(居然平均4.5行一個),印象中被删除的無用函數數量大約隻有50個以下,遠遠低于原來做過的50%左右的主觀感覺。

但也不用擔心老程式員“因自己需要”産生的函數不能滿足新程式員的新需要,若複用設計做到足夠好,新程式員很少需要再編寫什麼新函數了。

不過,要讓代碼真正複用,需要做一點小範圍管理——在松結對程式設計和139團隊模式下,困難不大——具體包括:

1. 每當高手新增一個可複用類或函數時,“告知”一下團隊。

在我們的環境中,“吼一聲”足夠了。

2. 當新手想用或開發什麼可複用類或函數時,問一下高手。

這個很重要,新手常常也有主動複用的沖動,不過重新發明輪子的可能性居多。

3. 當新手的需求引發底層庫改動時,可以采用松結對程式設計。

一般允許新手檢視和改動底層庫,這是一個很好的學習機會;通過轉移知識,高手也可以把底層庫的維護轉交給新手,避免成為新手的工具包(在三型代碼中,往往正是如此)。

高手可以在修改時提供一些指導,比如用10分鐘先描述一下原來的工作原理,并建議在哪些地方進行改動。

新手常常想沒事就打開這些底層庫一探究竟,不過我發現這種無動機的學習效果很差。應該抓住新手需要新底層代碼的機會,讓他們學習并接手某些底層。

L型代碼的品質與三型代碼大緻相當,多次重用導緻缺陷無處藏身。

實際上L型代碼的底層庫甚至不太需要單元測試,品質就可能很高了。因為任何缺陷都會被不同的上層應用所發現,無需人為測試。(這個造成了另外一些問題)

由于高手隻在需要時才開發底層代碼,是以鍍金被有效杜絕。

L型代碼結構是以成了一種高品質高效率的程式設計管理方法。

前一段時間,我們突然被L型代碼産生的缺陷而困擾。這些缺陷從哪裡來的呢?

由于開發接近尾聲,我們決定通路一些早期就開發了但很少使用的上層功能來進行一些有限的測試。結果發現由于它們與新功能調用相同的底層,而底層每次因新功能被改動後都沒有回來驗證這些舊功能是否還能運作,是以這些功能中很多已經不能運作了,甚至無法打開頁面。

這件事後來的解決方法是:自動化回歸測試。我們花費大約一周建立了多數功能頁面的回歸測試,每次送出代碼前(有可能修改了底層代碼),都會習慣性地跑一遍,确認所有功能都正常運作。若失敗,則修改後再送出。

應該說,任何形式的複用包括L型代碼結構,都應該配合自動化回歸測試。

本文轉自火星人陳勇 51CTO部落格,原文連結:http://blog.51cto.com/cheny/1101546