設計模式解析學習筆記1——面向對象泛型

本系列筆記都是記錄設計模式的學習過程,會記錄一些書中比較重要的東西和本身的心得,書名爲《設計模式解析》。程序員

功能分解

將一個問題分解成多個功能步驟,解決更小的問題要比解決整個問題更簡單。設計模式

功能分解一般會有一個「主」程序負責控制子程序,主程序須要協調各個函數並控制它們的前後順序。這種方法會產生兩個問題:模塊化

  • 若是問題比較大,寫出的代碼會很是複雜
  • 若是需求改變,修改代碼將十分麻煩

對於第一個問題,咱們可讓子程序承擔更多的責任,讓子程序負責本身的行爲,並且讓主程序知道它能夠執行這個任務,這樣程序的邏輯就不會那麼複雜了,這就是所謂的委託(delegation)。函數

對於開發人員來講,需求永遠都不會是完整的、一成不變的,編寫可以很好的處理需求變動的代碼不是一件容易的事情。書中有這樣一句話:「雖然咱們沒法預測會發生什麼變化,可是咱們一般能夠預測到那裏會發生變化。與其抱怨需求老是變化,不如改變開發過程,從而更有效的應對變化」。學習

面向對象的巨大優勢之一,就是能夠封裝變化的區域,從而更容易的將代碼與變化產生的影響隔離開來。使用模塊化封裝變化後,有新的需求時,只須要改變這個模塊便可。但這種方法仍然存在問題,就是若是模塊的輸入數據若是發生變化,這種方法就不適用了。設計

模塊化確定有助於提高代碼的可理解性,使代碼更容易維護,可是模塊化並不能應對全部的需求變化。這種方法存在兩個問題:低內聚和緊耦合。調試

  • 內聚性(cohesion):有人成爲清晰性(clarity),指的是「例程(能夠理解爲類)中操做(理解爲函數)之間聯繫的緊密程度」。低內聚指的是一個類任務不少並且互不相關,代碼讓人看起來想是使人疑惑的一大團。有人稱之爲「上帝對象」,由於他們好像是萬能的。。。
  • 耦合性(coupling):指的是「兩個例程之間聯繫的緊密程度」。

耦合性與內聚性是相輔相成的關係,內聚性描述的是內部組成部分之間的相互關聯的緊密程度,而耦合性是指例程之間聯繫的緊密程度。軟件開發的目標應該是建立這樣的例程:內部完整(高內聚),而與其餘例程之間的聯繫則是小巧、直接、可見、靈活的(鬆耦合)。對象

對於程序員來講,最痛苦的莫過於調試bug,可是更痛苦的是調試完這個bug,卻對代碼的其它地方形成了意想不到的影響,事實上,咱們花費了更多的時間去修復由於修復bug而致使的其它問題。繼承

這就是功能分解的弊端,需求的變動會對軟件的開發和維護產生極大的影響。對一組函數或者數據的修改將會影響到其它的函數和數據,就像滾雪球同樣,會致使更多的變化,並且難以免。開發

應對需求變動

爲了找出解決需求變動問題的解決辦法,找到代替功能分解的方法,下面經過一個生活中的例子進行說明:假設你是一個會議上的講師,聽課的人在課後還要去聽其它的課,但他們不知道下一堂課的聽課地點。你的責任之一就是確保你們都能順利的去上下一堂課。

按照結構化程序設計方法,通常會經過下面方法:

  • 獲取聽課人的名單
  • 對名單上的每一個人進行下面操做
    • 找到他下一堂要聽的課
    • 找到該課的聽課地點
    • 找到去下一節課怎麼走
    • 告訴這我的怎麼去上下一堂課

這種方法只是理論上的方法,若是真的在現實生活中去作,估計沒有一我的會這樣作。最可能的作法就是把全部到其它教室的路線寫到黑板上,而後告訴他們讓他們本身去下一個教室。

第一種方法你須要找到每個人,告訴他們怎麼作,要對一切負責。而第二種方法只須要給出提示,每一個人就能夠本身去完成,每一個學生對本身負責。

如今若是需求進行了變動,須要一些研究生在上下一節課以前先收集學生對本節課的評價並交到辦公室。若是是使用上面第一種方法,就須要修改控制程序,判斷學生是普通學生仍是研究生,而後給研究生額外的任務,對程序的改動較大。若是是使用第二種方法,則不用修改控制程序,只須要再爲研究生編寫一個模塊便可。

這兩種方法的區別就是誰負責,第一種方法是主程序負責,而第二種方法將責任轉移到了每個學生的身上。

爲了便於理解,書中給出了下面三個概念。在UML Distilled一書中,Martin Fowler描述了軟件開發過程當中的三個不一樣視角:

  • 概念:這種視角呈現了所研究領域中的各類概念,得出概念模型時應該不多或者不考慮實現它的軟件。這個視角要回答的問題是:軟件要負責什麼?
  • 規約:這種視角考慮的是軟件,但關注的是軟件的藉口,而不是實現。這個視角要回答的問題是:怎麼使用軟件?
  • 實現:這是咱們考慮的是代碼自己,這多是最經常使用的視角,但在許多方面,採起規約視角常常會更好。這個視角回答的問題是:軟件怎樣履行本身的責任?

結合上面的例子,做爲講師你是在概念層次上與人交流,換句話說你要告訴學生的是「你要他們作什麼」,而不是「要他們如何去作」。可是,做爲學生則是很是明確的知道本身該如何去下一堂課的教室,這是在實現層進行的。

在概念層上交流,在實現層上執行,這樣主控程序就無需準確的知道操做具體細節,只須要概念性的知道便可。只要概念不變,請求者就與實現細節的變化隔離開了。

面向對象泛型

對象是什麼?對象傳統上被定義爲帶有方法的數據。

使用對象的優勢在於能夠定義本身負責本身的事物。對象天生就知道本身的類型,對象中的數據可以告訴它本身是什麼狀態,而對象中的代碼可以讓它知道本身能作什麼。

聯繫上面說的軟件開發的三個視角,能夠這樣理解面向對象:

  • 在概念層次上,對象是一組責任。
  • 在規約層次上,對象是一組能夠被其它對象或對象本身調用的方法。
  • 在實現層次上,對象是代碼和數據,以及他們之間的計算交互。

類是對對象行爲的定義,它包含如下內容的完整描述:

  • 對象所包含的數據元素。
  • 對象可以操做的方法。
  • 訪問這些數據元素和方法的方式。

要得到一個對象時,要告訴程序須要某一個類型(也就是對象所屬的類)的一個新對象,這個新對象爲類的一個實例。建立對象的過程成爲實例化。

面向對象的三個特徵是封裝、繼承、多態。

相關文章
相關標籤/搜索