2008年11月15日 星期六

[Head First OOAD] 偉大軟體由此開始:良好應用程式之基石

開發偉大軟體的三個步驟

  1. 確認你的軟體作客戶要它作的事情 (此步驟把重點放在客戶上,確保應用程式作它應該先作的事。這裡是收集需求(requirement)與分析(analysis)工作所著力之處)

  2. 應用基本的 OO 原則,增加軟體的彈性 (一旦軟體開始運作,你能找出任何可能因疏忽而產生的重複程式碼,並且確認你再使用良好的 OO 編程技術)

  3. 努力達成可維護、可重利用的設計 (得到作它該作之事的良好物件導向應用程式? 是時候了,運用設計模式與 OO 原則,確保你的軟體準備就緒)

enum 的妙用


在 class 的某些屬性,若是只有幾種可能性,則可以用 enum 來處理。

Q1:什麼是 enum ?

Ans
:enum 是列舉型別,C、C++ 或是 Java 5.0 以上都有支援。

以 color 為例,有可能會有 red、blue、yellow、green … 等等,但種類絕對不會有太多種 (特殊應用例外!),這種情況就相當適合使用 enum;簡單來說,只要具有「具有標準範圍或合法值」的特性,都適合用 enum 來表示,可以避免取得壞資料。

以下用一段範例程式碼來說明:



Q2:使用 enum 的好處有哪些呢 ?

Ans
:使用 enum 的 method 或 class,會受到它的保護,確保不會出現未定義在 enum 中的值,即使是打錯或是拼錯,compiler 也會提醒改正。不僅可以確保 type 的安全,也可以確保 value 的安全。

比較以下兩張 class diagram 的設計:

原本的設計



使用 enum 後的改變




基本 OO 原則的思維


1、物件應該作其名稱所指之事

假如物件名稱為 Jet,它可能應該 talkOff() 與 land(),而不應該 takeTicket() - 那是其他物件的工作,不屬於 Jet。

2、每個物件應該代表單一概念

不要讓物件服務雙重或三重責任。避免使用一個 Duck 物件,同時代表會呱呱叫的真正鴨子或是黃色的塑膠鴨。

3、未使用的特性是無用的贈品

假如你有一個物件,經常具有空值或 null 的特性,你可能有一個物件在作一種以上的工作。假如物件中的某個特性很少有值,為何該特性是此物件的一部份? 要不要有一個較好的物件,僅使用原有特性的子集(subset)?

仔細留意前面的 Inventory class diagram,每次顧客要作 search() 的動作時都必須要傳入一個 Guitar 物件,但這個物件的 serialNumber 與 price 永遠都不指定(正是上面第三點說的未使用特性),所以衍生出一個問題:

既然每次都不指定,那可以另外制訂一個 class 來專門處理 Guitar 的規格嗎?

當然是可以的,因為在書中就提出了一個 GuitarSpec 類別來解決這個問題:
看吧! 透過設計一個 GuitarSpec 類別,達成了上述的三個原則!
  1. GuitarSpec 所做的事就只有負責與規格相關的事情,其他一概不管。

  2. GuitarSpec 就是只能代表吉他的規格,也不會突然可以代表小提琴的規格。

  3. 客戶在進行搜尋時,可以專注於規格,無用的 serialNumber 與 price 就可以丟掉囉!

  4. 重點是:程式碼不重複。

委派(Delegation)


委派是當物件需要執行某項工作時,不是直接進行該工作,而是要求另一個物件代為處理。

委派可讓程式碼更能重利用,也讓每個物件關注自己的功能,而不是把處理單一物件行為的程式碼分散在整個應用程式。

委派讓每個物件自己去擔心相等性(或某種其他工作)。這表示物件彼此獨立(鬆散隅合;loosely coupled)。
  1. loosely coupled 的物件可以從一個應用程式取出,並輕易的在另一個應用程式中重利用,因為他們並未緊密繫結到其他物件的程式碼。

  2. loosely coupled 意味著應用程式裡的各個物件各有特定工作要作,而且只作那項工作。

  3. loosely coupled 的應用程式通常比較有彈性,且容易變更。因為每個物件都相當獨立於其他物件,因此可以改變一個物件的行為,而不必牽動所有其他物件,如此一來增加新功能或特色就變的容易多了。

當 GuitarSpec 內容改變時

當 GuitarSpec 中增加屬性(numStrings)時,以先前設計來說,會有什麼結果呢?
解決方式為:
  1. 將與 GuitarSpec 相關的事務都封裝進 GuitarSpec class 中。

  2. 將 Inventory 的 search() method 委派由 GuitarSpec class 來處理。

重點總結


  1. 脆弱的應用程式是很容易出錯的。

  2. 運用類似封裝或是委派的 OO 原則建造有彈性的應用程式。

  3. 封裝將應用程式分解成合乎邏輯的零件。

  4. 委派將處理特定工作的責任轉交給另一個物件。

  5. 總是透過客戶要什麼,來啟動你的專案。

  6. 一旦完成基本功能,就重新精鍊你的設計,讓它有彈性。

  7. 有了符合功能並具有彈性的設計,便能運用設計模式,進一步改善你的設計,讓應用程式更容易重利用。

  8. 找出應用程式經常改變的部分,試著將它們與其他不改變的地方相分離。

  9. 建造運作無誤但設計不良的應用程式,滿足了你的客戶,卻留給自己痛苦,以及無數的修正問題的不眠夜。

  10. 物件導向分析與設計(OOA&D)提供一種產生設計良好之應用程式的方法,同時滿足客戶與程式設計師。

沒有留言:

張貼留言