軟體設計最大的敵人,就是應付需求不斷的變化。變化有時候是無窮盡的,於是專案開發就在反覆的修改、更新中無限期地延遲交付的日期。變化如懸在頭頂的達摩克斯之劍,令許多軟體工程專家一籌莫展。正如無法找到解決軟體開發的「銀彈」,要徹底將變化扼殺在搖籃之中,看來也是不可能完成的任務。那麼,積極地面對「變化」,方才是可取的態度。於是,極限程式設計(xp)的倡導者與布道者kent beck提出要「擁抱變化」,從軟體工程方法的角度,提出了應對「變化」的解決方案。而本文則試圖從軟體設計方法的角度,來**如何在軟體設計過程中,解決未來可能的變化,其方法就是——封裝變化。
設計模式是「封裝變化」方法的最佳闡釋。無論是建立型模式、結構型模式還是行為型模式,歸根結底都是尋找軟體中可能存在的「變化」,然後利用抽象的方式對這些變化進行封裝。由於抽象沒有具體的實現,就代表了一種無限的可能性,使得其擴充套件成為了可能。所以,我們在設計之初,除了要實現需求所設定的用例之外,還需要標定可能或已經存在的「變化」之處。封裝變化,最重要的一點就是發現變化,或者說是尋找變化。
gof對設計模式的分類,已經彰顯了「封裝變化」的內涵與精髓。建立型模式的目的就是封裝物件建立的變化。例如factory method模式和abstract factory模式,建立了專門的抽象的工廠類,以此來封裝未來物件的建立所引起的可能變化。而builder模式則是對物件內部的建立進行封裝,由於細節對抽象的可替換性,使得將來面對物件內部建立方式的變化,可以靈活的進行擴充套件或替換。
至於結構型模式,它關注的是物件之間組合的方式。本質上說,如果物件結構可能存在變化,主要在於其依賴關係的改變。當然對於結構型模式來說,處理變化的方式不僅僅是封裝與抽象那麼簡單,還要合理地利用繼承與聚合的方法,靈活地表達物件之間的依賴關係。例如decorator模式,描述的就是物件間可能存在的多種組合方式,這種組合方式是一種裝飾者與被裝飾者之間的關係,因此封裝這種組合方式,抽象出專門的裝飾物件顯然正是「封裝變化」的體現。同樣地,bridge模式封裝的則是物件實現的依賴關係,而composite模式所要解決的則是物件間存在的遞迴關係。
行為型模式關注的是物件的行為。行為型模式需要做的是對變化的行為進行抽象,通過封裝以達到整個架構的可擴充套件性。例如策略模式,就是將可能存在變化的策略或演算法抽象為乙個獨立的介面或抽象類,以實現策略擴充套件的目的。command模式、state模式、vistor模式、iterator模式概莫如是。或者封裝乙個請求(command模式),或者封裝一種狀態(state模式),或者封裝「訪問」的方式(visitor模式),或者封裝「遍歷」演算法(iterator模式)。而這些所要封裝的行為,恰恰是軟體架構中最不穩定的部分,其擴充套件的可能性也最大。將這些行為封裝起來,利用抽象的特性,就提供了擴充套件的可能。
利用設計模式,通過封裝變化的方法,可以最大限度的保證軟體的可擴充套件性。面對紛繁複雜的需求變化,雖然不可能完全解決因為變化帶來的可怕夢魘,然而,如能在設計之初預見某些變化,仍有可能在一定程度上避免未來存在的變化為軟體架構帶來的災難性傷害。從此點看,雖然沒有「銀彈」,但從軟體設計方法的角度來看,設計模式也是一枚不錯的「銅彈」了。
封裝變化(三)
設想這樣乙個需求,我們需要為自己的框架提供乙個負責排序的元件。目前需要實現的是氣泡排序演算法和快速排序演算法,根據 面向介面程式設計 的思想,我們可以為這些排序演算法提供乙個統一的介面isort,在這個介面中有乙個方法sort 它能接受乙個object陣列引數。對陣列進行排序後,返回該陣列。介面的定...
封裝變化 Part Three
filed under design pattern bruce zhang 6 35 pm 設想這樣乙個需求,我們需要為自己的框架提供乙個負責排序的元件。目前需要實現的是氣泡排序演算法和快速排序演算法,根據 面向介面程式設計 的思想,我們可以為這些排序演算法提供乙個統一的介面isort,在這個介面...
封裝變化(三)
設想這樣乙個需求,我們需要為自己的框架提供乙個負責排序的元件。目前需要實現的是氣泡排序演算法和快速排序演算法,根據 面向介面程式設計 的思想,我們可以為這些排序演算法提供乙個統一的介面isort,在這個介面中有乙個方法sort 它能接受乙個object陣列引數。對陣列進行排序後,返回該陣列。介面的定...