天天看點

活用 XP: (三)實踐疊代

活用 XP: (三)實踐疊代

林星(轉載自www-900.ibm.com)    2003年10月27日

  在了解了分階段開發軟體的基本思路之後,緊接着就需要考慮實施的問題。分階段開發最難的,并不是在過程的控制上,而是在軟體設計能力上。

應用疊代的問題

  有一則故事說的是一個人肚子疼,去看醫生,醫生給他開了眼藥,理由是眼神不好,吃錯了東西,是以才會肚子疼。軟體開發中出現的問題往往不是單純的問題,頭疼醫頭,腳疼醫腳的做法未必适合于軟體開發。

  應用疊代并不是一件簡單的事情,懂得了疊代和增量的概念,并不等于你能夠用好它們。為什麼這麼說呢?很多的軟體組織嘗試着運用疊代開發,但是結果卻不盡人意,于是将問題怪罪在疊代的方法不切實際上。軟體工程中有句著名的話?quot;沒有銀彈"。疊代和增量也不是什麼銀彈。要想做好疊代,缺乏優秀的軟體設計思想和高明的軟體設計師的支援是不行的。在XP中,非常強調各項實踐的互為補充。在我看來,疊代能夠順利實行的思路需要重構、測試優先、持續內建等的直接支援。而這些實踐,展現了軟體設計和軟體過程中的關系。

  疊代實踐出現問題往往是在項目的中期。這個時候,軟體的主體已經形成,代碼的增長速度也處于一個快速增長的情況。這種狀态下的軟體開發對變化的需求是最沒有抵抗力的,尤其是那些設計本身存在問題的軟體。軟體開發到這個階段,代碼往往比較混亂,缺乏一條主線或是基礎的架構。這時候,需求的變化,或是新增的需求導緻的成本直線上升,項目進度立刻變得難以預期,開發人員的士氣受到影響。

疊代之外的解決方法

  在這個時候,軟體組織要做的,并不是在疊代這個問題上深究下去,而是應當從軟體設計入手,找到一種能夠适應變化的軟體設計思路或方法。例如,你是否應該考慮在面向對象領域做一些研究呢?面向對象的思路很注重将變化的内容和不變的内容相區分,以便支援未來的變化和應對不确定性。然後你再來考慮相應的成本。

做好疊代有幾個值得注意的地方:

代碼設計優化

  軟體開發的能力并不展現為代碼量的多少,而是展現為代碼實作的功能,代碼的可擴充性、可了解性上。是以對代碼進行不斷的改進,對設計進行不斷的改進(具體的次數根據需要而定),使軟體的結構比較穩定,并能夠支援變化。這是疊代的一個前提。否則,每一次的疊代都花費大量的精力來對原先的設計進行修改,對代碼進行優化,這樣的疊代效率是不高的,也可以視為一種浪費。堅持不斷改進軟體品質的做法其實是将軟體的集中維護、改進的成本分攤到整個過程中,這種思路,和全面品質管理的思路是非常類似的。XP中的重構實踐有一個修飾詞,稱為無情。這充分表現了XP的異類,但是應該承認,隻有設計和代碼的品質上去了,才能夠為後續的疊代過程打下一個基礎,更何況,XP所處的往往是一個不确定的、變化多端的環境。正是因為這種環境對軟體開發有着很大的影響,是以代碼品質也被高度的重視。不同的行業,不同的項目,需要根據自己的特征進行調整,但是,隻有保證代碼的優美性,才能夠順利地達成疊代的目标。

  代碼設計優化同時必須保持簡單的原則,不在一開始進行大量的設計投入。我曾堅信,軟體編碼之前,嚴格的軟體設計是不可或缺的。但是慢慢的,我發現這種思路未必是正确的。在總結了一些開發經驗之後,我發現,很多的時間其實是浪費在了設計上。

  在一個軟體的設計中,對界面結構有着很強的要求,而Eclipse的設計思路正當其時。是以,我興奮的将Eclipse的設計思路注入到界面設計上來,在花費了大量的時間進行設計和實作之後,發現并不能很好的滿足需要。更為糟糕的是,由于設計的複雜性,導緻調試和變更的難度都加大,而團隊的其它成員,也表示難以了解這種思路。最後的這個設計廢棄了,但是損失已經是造成了,複雜的設計和實作,足足花費了一個星期的開發時間。

重構和審查

  除了第一次的疊代,後續的疊代過程都是建立在前一次疊代的基礎上。是以,每一次疊代中積累下來的問題最終都會反應在後續的疊代過程中。要想保證疊代順利的進行,對代碼進行重構和審查是少不了的工作。其中最重要的工作莫過于消除重複代碼,重複代碼是造成代碼雜亂的罪魁禍首。消除重複代碼的工作可不僅僅隻是找出公函這麼簡單,其間涉及到重構、面向對象設計、設計模式、架構等衆多的知識。這些知識的介紹并不是本文的重點,但是我們必須知道,隻有嚴格的控制好代碼的品質,軟體的品質和軟體過程的品質才有保證。

推遲設計決策

  精益程式設計告訴我們,盡可能推遲決策。在一個變化的環境中,早期的決策往往缺乏足夠的事實支援和實踐證明。即便是再高明的軟體設計師,難免會犯錯誤,這是非常正常的,那麼,既然目前的決定是有着很大風險的,那為什麼我們還要急于做出決定呢?在看待設計這個問題上,一種比較好的做法是,盡量避免高難度、高浪費的設計,以滿足現有的需要作為實作的目标。未來的需求等到确定的時候再進行調整。

  推遲決策其實是軟體設計的一大能力,為什麼我們會推薦使用面向對象技術呢?因為面向對象技術具有很強的推遲決策的能力,先将目前确定的問題納入面向對象設計,并為未來的不确定性留下擴充。推遲決策并不是一個簡單的問題,它需要很強的面向對象的設計思維能力。

  設計模式中有很多這方面的例子,其中的裝飾模式具有很強的代表性。

活用 XP: (三)實踐疊代

  在設計剛開始的時候,沒有人知道ConcreteComponent最後的發展會是什麼樣。很明顯,這是一個處于不确定環境中的設計,我們唯一能夠确定的,隻有Component這個類體系一定會擁有Operate這個方法,是以,我們設計了一個接口Component來限制類體系,要求所有的子類都擁有Operate方法。另一個目的是為用戶端調用提供了統一的接口,這樣,用戶端對服務端資訊的了解到了最小的程度,隻需要知道Operate這個方法,并選擇适當的類就可以了。還可以對這個模型做進一步的改進,令耦合程度進一步降低。

  在統一了接口之後,我們就可以根據需要來實作現有的功能,我們實作了一個ConcreteComponent類,它實作了Component接口,并實作了核心的功能。如果在未來,需求的變化,要求我們增加額外的行為,我們就使用ConcreteDecorator類來為ConcreteComponent添加新的功能:

public class ConcreteDecorator implement Component

{

private Component component;

public void Operate()

{

//額外的行為

component.Operate;

}

}

  先找出共通點,然後實作共通點,并把不确定的資訊設計為擴充,這就是推遲決策的設計思路。但是,應該指出的是,上面這個例子的設計,仍然有很多的限制,例如,增加的需求(也就是某個ConcreteDecorator)中可能擁有新的接口,例如需要一個AnotherOperate方法,這時候,原先的擴充性設計就又變得難以滿足需要了。在軟體設計中,針對接口設計的靈活性和擴充性雖然比以往的設計增強的許多,但它并不是萬能的,而且取決于設計師對需求的了解能力和設計水準。此外,推遲設計決策要求我們學習抽象的思維,識别和區分軟體中變化和不變的部分。

注重接口,而不是注重實作

  Martin Fowler把軟體設計分為三個層面:概念(conceptual)層面、規約(Specification)層面、實作(Implementation)層面。軟體的設計應該盡可能地站在概念、規約層面上進行,而不是過分關注實作層面。之是以有時候我們發現在疊代的過程中,軟體難以承受這種變化,那麼,很大的可能是規約層面和實作層面出了問題。我們在前面一節讨論重構和審查的時候說,消除重複代碼是一項複雜的工作,針對規約設計就是其中最有效,但也是最難的一種方法。

  我們可以把規約層面想象為軟體的接口或是抽象類,或是具體類的公有方法,而把實作層面想象為實作類、實作細節。那麼,我們的原則應該盡可能設計穩定的規約層面,并為客戶(可能是真正的客戶,大部分情況下是使用你的代碼的客戶程式員)提供一個優秀的、簡單的界面(接口)。社會發展到現在的水準,任何一個人都不會花費過多的時間來研究你的代碼,如果你的代碼不能夠為他人提供便利性,那麼最後被淘汰的一定就是你的代碼。Java語言的成功,很大程度上就在于他在保證其強大功能的同時,還提供了一個簡單、易用、清晰的規約界面。

  在軟體設計中,重視規約層面的設計是很普遍的。為什麼我們提倡三層架構的軟體設計?最重要的是因為他為軟體結構合理性貢獻巨大,遠遠超過了他的其它價值。在現代的軟體設計中,資料庫、界面、業務模組化其實是三種差異較大的技術,這就導緻了三者的變化度是不同的。根據區分不同變化度的原則,我們知道,必須對三種技術進行區分。而這正是三層架構的主要思路。從這個思路擴充出去,我們還可以根據變化度的需要,将三層架構演變為四層架構、甚至多層架構。而多個層次之間,正是通過優秀的規約界面來達到最松散的耦合的。

  在精益程式設計中,為了避免浪費,要求每位程式員提高代碼的規約層面的穩定性是非常有必要的。一個系統中,設計優良的規約界面能夠擁有比較好的抗變化能力,能夠較好的适應疊代過程。

回歸

  版本2的軟體出現了版本1中不存在的行為,稱為回歸。回歸是軟體開發中的主要問題。在對現有功能修改的同時影響原有的行為,這是造成bug的主要原因。在疊代的過程中,必須避免回歸行為的出現。而避免回歸問題的主要解決方法是建構自動化的測試,實作回歸測試。

  成功建構回歸測試的關鍵仍然在于是否能夠設計出優秀的規約界面,并針對規約界面進行測試。這樣,不但設計具有抗變化性,測試同樣具有抗變化性。而唯一可能改變的就隻有實作了。在回歸測試的幫助下,代碼的變化是不足為懼的。我們把有關測試的詳細讨論放在測試一節中。

組織規則

  在後續的章節中,我們會詳細的讨論XP中的一項非常有特點的組織規則-結對程式設計。這裡我們需要知道,不同的團隊有着不同的組織,其疊代過程也需要應用不同的組織規則。例如,組織的規模,小規模的組織可以應用更快的疊代周期,如一周,在一個疊代周期中,團隊可以集中力量來開發一個需求,強調重構和測試,避免過多的前期設計。對于大的組織來說,可以考慮疊代周期更長一些,更注重前期設計,并将開發人員和測試人員的疊代周期交錯開來。團隊的組織構成也是影響疊代過程的主要原因。團隊是否都是由相同水準的人構成,每個人的專長是否能夠互補,團隊是否存在溝通問題。