在最開始,可將范式想象成一種特別聰明、能夠自我適應的手法,它可以解決特定類型的問題。也就是說,它類似一些需要全面認識某個問題的人。在了解了問題的方方面面以後,最後提出一套最通用、最靈活的解決方案。具體問題或許是以前見到並解決過的。然而,從前的方案也許並不是最完善的,大家會看到它如何在一個范式裡具體表達出來。
盡管我們稱之為“設計范式”,但它們實際上並不局限於設計領域。思考“范式”時,應脫離傳統意義上分析、設計以及實施的思考方式。相反,“范式”是在一個程序裡具體表達一套完整的思想,所以它有時可能出現在分析階段或者高級設計階段。這一點是非常有趣的,因為范式具有以代碼形式直接實現的形式,所以可能不希望它在低級設計或者具體實施以前顯露出來(而且事實上,除非真正進入那些階段,否則一般意識不到自己需要一個范式來解決問題)。
范式的基本概念亦可看成是程序設計的基本概念:添加一層新的抽象!只要我們抽象了某些東西,就相當於隔離了特定的細節。而且這後面最引人注目的動機就是“將保持不變的東西身上發生的變化孤立出來”。這樣做的另一個原因是一旦發現程序的某部分由於這樣或那樣的原因可能發生變化,我們一般都想防止那些改變在代碼內部繁衍出其他變化。這樣做不僅可以降低代碼的維護代價,也更便於我們理解(結果同樣是降低開銷)。
為設計出功能強大且易於維護的應用項目,通常最困難的部分就是找出我稱之為“領頭變化”的東西。這意味著需要找出造成系統改變的最重要的東西,或者換一個角度,找出付出代價最高、開銷最大的那一部分。一旦發現了“領頭變化”,就可以為自己定下一個焦點,圍繞它展開自己的設計。
所以設計范式的最終目標就是將代碼中變化的內容隔離開。如果從這個角度觀察,就會發現本書實際已采用了一些設計范式。舉個例子來說,繼承可以想象成一種設計范式(類似一個由編譯器實現的)。在都擁有同樣接口(即保持不變的東西)的對象內部,它允許我們表達行為上的差異(即發生變化的東西)。合成亦可想象成一種范式,因為它允許我們修改——動態或靜態——用於實現類的對象,所以也能修改類的運作方式。
在《Design Patterns》一書中,大家還能看到另一種范式:“繼承器”(即Iterator,Java 1.0和1.1不負責任地把它叫作Enumeration,即“枚舉”;Java1.2的集合則改回了“繼承器”的稱呼)。當我們在集合裡遍歷,逐個選擇不同的元素時,繼承器可將集合的實施細節有效地隱藏起來。利用繼承器,可以編寫出通用的代碼,以便對一個序列裡的所有元素采取某種操作,同時不必關心這個序列是如何構建的。這樣一來,我們的通用代碼即可伴隨任何能產生繼承器的集合使用。