n 不必要的復雜性: 設計中包含有不具任何直接好處的基礎結構。
n 不必要的重復性: 設計中包含有重復的結構,而該重復的結構本可以使用單一的抽象進行統一。
n 晦澀性: 很難閱讀、理解。沒有很好地表現出意圖。
敏捷團隊依靠變化來獲取活力。團隊幾乎不進行預先設計,因此,不需要一個成熟的初始設計。他們更愿意保持設計盡可能的干凈、簡單,并使用許多單元測試和驗收測試作為支援。這保持了設計的靈活性、易于理解性。團隊利用這種靈活性,持續地改進設計,以便于每次迭代結束生成的系統都具有最適合于那次迭代中需求的設計。
為了改變上面軟件設計中的腐化味,敏捷開發采取了以下面向對象的設計原則來加以避免,這些原則如下:
n 單一職責原則(SRP)
就一個類而言,應該僅有一個引起它變化的原因。
n 開放-封閉原則(OCP)
軟件實體應該是可以擴展的,但是不可修改。
n Liskov替換原則(LSP)
子類型必須能夠替換掉它們的基類型。
n 依賴倒置原則(DIP)
抽象不應該依賴于細節。細節應該依賴于抽象。
n 接口隔離原則(ISP)
不應該強迫客戶依賴于它們不用的方法。接口屬于客戶,不屬于它所在的類層次結構。
n 重用發布等價原則(REP)
重用的粒度就是發布的粒度。
n 共同封閉原則(CCP)
包中的所有類對于同一類性質的變化應該是共同封閉的。一個變化若對一個包產生影響,則將對該包中的所有類產生影響,而對于其他的包不造成任何影響。
n 共同重用原則(CRP)
一個包中的所有類應該是共同重用的。如果重用了包中的一個類,那么就要重用包中的所有類。
n 無環依賴原則(ADP)
在包的依賴關系圖中不允許存在環。
n 穩定依賴原則(SDP)
朝著穩定的方向進行依賴。
n 穩定抽象原則(SAP)
包的抽象程度應該和其穩定程度一致。
上述中的包的概念是:包可以用作包容一組類的容器,通過把類組織成包,我們可以在更高層次的抽象上來理解設計,我們也可以通過包來管理軟件的開發和發布。目的就是根據一些原則對應用程序中的類進行劃分,然后把那些劃分后的類分配到包中。
下面舉一個簡單的設計問題方面的模式與原則應用的示例:
問題:
選擇設計運行在簡易臺燈中的軟件,臺燈由一個開關和一盞燈組成。你可以詢問開關開著還是關著,也可以讓燈打開或關閉。
解決方案一:
下面圖1是一種最簡單的解決方案,Switch對象可以輪詢真實開關的狀態,并且可以發送相應的turnOn和turnOff消息給Light。
解決方案二:
上面這個設計違反了兩個設計原則:依賴倒置原則(DIP)和開放封閉原則(OCP),DIP原則告訴我們要優先依賴于抽象類,而Switch依賴了具體類Light,對OCP的違反是在任何需要Switch的地方都要帶上Light,這樣就不能容易擴展Switch去管理除Light外的其他對象。為了解決這個方案,可以采用ABSTRACT SERVER模式,在Switch和Light之間引入一個接口,這樣就使得Switch能夠控制任何實現了這個接口的東西,這也就滿足了DIP和OCP原則。如下面圖2所示:
解決方案三:
上面圖2所示解決方案,違返了單一職責原則(SRP),它把Switch和Light綁定在一起,而它們可能會因為不同的原因而改變。這種問題可以采用ADAPTER模式來解決,適配器從Switchable 派生并委托給Light,問題就被優美的解決了,現在,Switch就可以控制任何能夠被打開或者關閉的對象。但是這也需要會出時間和空間上的代價來換取。如下面圖3所示:
敏捷設計是一個過程,不是一個事件。它是一個持續的應用原則、模式以及實踐來改進軟件的結構和可讀性的過程。它致力于保持系統設計在任何時間都盡可能得簡單、干凈和富有表現力。
參考文獻
設計模式-可復用面向對象軟件的基礎 -- 李英軍等譯
重構-改善既有代碼的設計 -- 侯捷等譯
敏捷軟件開發-原則、模式與實現 -- 鄧輝譯
文章來源于領測軟件測試網 http://www.kjueaiud.com/