제이온

[物件] 第1章 物件,設計

  • 撰写语言: 韓国語
  • 基准国家: 所有国家country-flag
  • 信息技术

撰写: 2024-04-28

撰写: 2024-04-28 13:45

引言

羅伯特·L·葛拉斯主張實務優先於理論。特別是在軟體開發領域,實務往往領先於理論,開發人員在實際操作程式碼、親自動手時,才能獲得最多的經驗。因此,我們暫時將理論和概念放在一邊,先來看看一個簡單的程式範例。


實作票務應用程式

  • 為了宣傳小型劇院,我們打算策劃一場小型活動。
    • 活動內容:透過抽籤選出幸運觀眾,並寄送免費觀賞演出的邀請函。
  • 需要區分活動中獎和未中獎的觀眾。
    • 活動中獎觀眾:將邀請函兌換為門票。
    • 活動未中獎觀眾:需付費購買門票。



問題何在?

羅伯特·馬丁說明了軟體模組(無論大小,像是類別、套件、函式庫等構成程式的任意元素)應具備的三個功能。


  • 在執行時能正常運作。
  • 為了修改而存在。
    • 即使是簡單的修改,也必須能夠輕鬆完成。
  • 與閱讀程式碼的人溝通。
    • 開發人員必須能夠輕鬆閱讀和理解。


先前的票務應用程式滿足了第一個限制條件,也就是能正常執行,但卻無法滿足易於修改和溝通的目的。


出乎意料的程式碼

讓我們來看看為什麼無法滿足溝通的目的。


  • Theater 類別中的 enter() 方法的功能
    • 劇院會打開觀眾的包包,檢查裡面是否有邀請函。
    • 如果包包裡有邀請函,劇院會指示售票員將售票口保管的門票移到觀眾的包包裡。
    • 如果包包裡沒有邀請函,劇院會從觀眾的包包裡拿出等於門票價格的現金,購買門票,然後將門票放進包包裡。
  • 從觀眾的角度來看,劇院這個第三方會隨意翻閱他們的包包,拿走他們的錢,然後把門票放進去,他們只能眼睜睜地看著。
  • 從售票員的角度來看,劇院這個第三方會在沒有許可的情況下操作售票口的門票和現金,他們只能眼睜睜地看著。
  • 可理解的程式碼是指其運作方式不會偏離我們預期的程式碼,而上述的劇院例子則超出了我們的預期。
    • 觀眾應該自行從包包裡拿出現金支付給售票員,然後領取門票。
    • 售票員應該自行從售票口取出門票交給觀眾,並收取觀眾的錢,然後將錢放回售票口保管。
  • 此外,要理解 enter() 方法,需要記住許多細節。
    • Audience 擁有 Bag。
    • Bag 裡面有現金和門票。
    • TiketSellet 在 TicketOffice 販售門票,TicketOffice 裡面保管著現金和門票。


容易受到修改影響的程式碼

enter() 方法假設了兩個條件。

  • 觀眾總是隨身攜帶包包來存放現金和邀請函。
  • 售票員只在售票口販售門票。


那麼以下情況會如何呢?

  • 觀眾可能沒有包包。
  • 觀眾可以使用信用卡而不是現金。
  • 售票員可以在售票口外販售門票。


例如,為了滿足第一個需求,我們需要刪除 Audience 的 Bag 物件,並修改與之相關的 Theater 類別中的 enter() 方法。這是因為 Theater 類別過於依賴觀眾攜帶包包以及售票員只在售票口販售門票等過於細節的事實。如果這些細節中的任何一個發生變化,就必須修改相關類別和依賴類別(例如:Theater)。


這與物件之間的依賴關係相關,而依賴關係暗示著修改的影響。但是,物件導向設計的目標是建立彼此依賴並協作的物件社群,因此,我們不是要無條件地消除依賴關係,而是要維持實現應用程式功能所需的最低限度的依賴關係並消除不必要的依賴關係。


物件之間依賴關係過多的情況稱為耦合度過高,兩個物件之間的耦合度越高,它們一起修改的可能性就越大。因此,設計的目標是降低物件之間的耦合度,以實現易於修改的設計。


改進設計

Theater 無需知道觀眾是否攜帶包包,以及售票員是否在售票口販售門票。Theater 只希望觀眾入場。因此,我們需要讓觀眾自行處理包包裡的現金和邀請函,讓售票員自行處理售票口的門票和銷售價格,使其成為自主的存在。


提升自主性

我們將只執行密切相關任務,並將不相關任務委派給其他物件的物件稱為內聚度高。建立能自行處理其資料的自主物件,可以降低耦合度並提高內聚度。


程序導向與物件導向

  • 程序導向
    • Theater 的 enter() 方法是程序,Audience、TicketSeller、Bag、TicketOffice 是資料。
    • 將程序和資料放在不同模組中的方式稱為程序導向程式設計。
    • 存在許多與我們的直覺相悖的程式碼。(例如:觀眾自行管理金錢和邀請函)
    • 難以縮小資料變更所造成的影響。
    • 以集中式方式管理責任。(Theater 管理所有內容)
  • 物件導向
    • 將資料和程序放在同一模組中的方式稱為物件導向程式設計。
    • 可以撰寫符合我們直覺的程式碼。
    • 可以透過封裝有效縮小資料變更所造成的影響。
    • 每個物件自行負責。


還可以進一步改進

  • Audience 類別中的 Bag 類別仍然是被動的存在,受 Audience 類別的控制,因此需要將 Bag 類別塑造成自主物件。
  • TicketSeller 類別中的 TicketOffice 也受到 TicketSeller 的控制。需要將 TicketOffice 塑造成自主物件。
    • 但是,修改後,TicketOffice 與 Audience 之間產生了額外的耦合度。
    • 像這樣,設計需要仔細權衡取捨。在這種情況下,為了降低與 Audience 的耦合度,可以協商將 TicketOffice 塑造成一定程度上的被動物件。



不,那是錯誤的!

  • 在現實世界中,即使是被動的存在,一旦進入物件導向的世界,也會變成主動且自主的存在。
  • 可以使用擬人化的方式,將被動的物件視為會笑、會說話、會生氣的對象。


物件導向設計

為什麼需要設計?

  • 設計就是安排程式碼。
  • 好的設計是指能夠完整滿足當前需求的功能,同時也能夠順利地容納未來的修改。


物件導向設計

  • 可修改的程式碼就是易於理解的程式碼。
  • 物件導向範式有助於我們以看待世界的方式撰寫程式碼。
  • 物件是自行負責其資料的自主存在。
  • 優秀的物件導向設計是指適當管理協作物件之間依賴關係的設計。


參考來源

  • 物件

评论0