Re: [請益] 我這樣解釋OOP對嗎?
看板Soft_Job (軟體人)作者gnimnek168 (Gnimnek168)時間8年前 (2017/11/13 16:06)推噓19(23推 4噓 23→)留言50則, 27人參與討論串6/19 (看更多)
1. 封裝 (encapsulation)
其實封裝本來就是人們面對複雜度的一種本能,針對某一問題點的廣度與深度之間找到適
切的焦點。鄧小平就曾說過:「不管黑貓或白貓,能抓到老鼠的就是好貓」。其實這就是把系
統當作黑箱 (black-box)的封裝概念了。 :)
設計模式 (DP, Design Pattern)內的「Facade」,即為強調封裝某一主體 (context)內
部繁雜的細節。
例如,兩大平台的 Web MVC (Model/View/Control)是一種因應 Web 端的技術解決方案,
實際上 Controller 僅為 UI 端的控制邏輯,卻不適合擔任資料存取(data access)與邏
輯運算(business logic)的工作。所以在大型系統的開發上,一般會設計中間層的「領域
物件 (domain controller)」,將上述兩大類的工作 (資料存取/邏輯運算)由其當窗口
(entry-poing),再視工作性質,委派 (delegate)給專司其職的成員物件 (如
DAO/Utility, Business Object ...等)。
此時「Domain Controller」就是一種系統的「Facade」物件,封裝了資料存取與邏輯運
算的細節,UI 端 (Web/Standalone Form/Mobile App/外部系統)不需要知道如何處理,
只要能取得所需要的結果即可。
不僅程式寫碼,在 UML 的使用案例 (use case)需求分析技術中,就擅用了封裝的技巧 (
系統功能(主題)->程序/工作事項->細節(資料欄位/計算邏輯)),先抓大的操作目的,再
來包容善變的細節。
在軟體工程來說,這比較能造成「低耦合 (low coupling)」的效果。
--------------------------------------------------------------------------------------------------
2. 繼承 (inheritance)=> 原意其實為「擴展 (extend)」較恰當
UML 是以「一般化-特殊化 (generalization-specialization」稱之更為適切。
特殊化類別「擴展(extend)」一般化類別有兩種用意:
a). 覆蓋 (override)預設的行為 (UML 稱 operation, OOP 稱 method)。
b). 擴展原來所沒有提供的行為。
舉個簡單的例子。「保險」有一預設的行為:計算保費(),但因為不同類型的保險,它們
的計算保費()邏輯實作均不一樣。「意外險」、「疾病險」、「壽險」均為「保險」的特
殊化類別,因為有著不同的實作方式,所以由各自的特殊化類別 (OOP 較喜愛稱為
sub-class)來分開個別實作。
這樣有什麼好處?財務人員可以用「一視同仁」的角度 (保險),藉由共同的操作目的 (
計算保費() )來操作所有的特殊化類別 (意外/疾病/壽險),但執行時 (run-time)卻是由
個別的特殊化類別負責實現。這樣自然就形成後述所提「多型 (polymorphism)」的效果
了。
未來要再擴展不同保險的類型,只要再新增特殊化類別即可 (當然要負責該實作邏輯),
用戶端 (Client)因為沒有直接耦合,自然無需作過多的修改,也不致讓程式碼越形冗長
擁腫了。
P.S. 上述僅是領域概念 (domain concept)的解釋,當轉至軟體的設計實作階段,會再更
講究精緻些,諸如分析保險的各種行為,而抽離出一群群 (group)的特殊化類別出來 (如
狀態群、業務邏輯群)。
--------------------------------------------------------------------------------------------------
3. 介面 (interface)/多型 (polymorphism)
介面 (對岸翻譯為接口)是一種隔離的設計應用,讓 Provider 不直接與眾多甚而
Unknown Client 耦合,僅透過標準的介面制定規格 (spec.)溝通。
介面的應用在生活面比比皆是。「IPowerSupply」介面制定「供電(電流,伏特)」的規格
,Provider (台電)提供符合該規格的服務,讓各類 Client (家電用品,電腦,遊戲機)只
要能符合標準規格即能取得該服務 (供應電力);至於若如筆電並不符合市電規格
(110V,20A),所以需要經由調變器 (adapter)來作轉型的工作。
軟體設計實務上,一般就會建議 DAO (Data Access Object)最好為其定義存取的操作介
面,將規格與實作隔離。如此爾後若實作內容(或實作技術)變動,並不致影響到 Client
端的運作。
多型上述已有提及,就是一種「一視同仁」的態度,來操作一般化的行為,但實作仍由各
種特殊化類別來負責。而廣義的多型設計,其實就不只限於所謂的「繼承體系 (再強調一
次,繼承這字眼不好,很容易誤導。一般化/特殊化這比較適切)」,它同時也涵蓋了介面
的應用,也就是一般化類型可以是具體(concrete)/抽象(abstract)類別,甚或完全沒有
實作的介面(interface)。
觀察設計模式所揭露諸多的物件模型,大致會分隔為上下兩層。上層的一般化往往都會視
現在已知/未來變動的權衡,而定義為抽象類別或介面,再由後續的特殊化類別來擴展
(extend)或實現(realize),Client 端永遠只與上層的一般化類型溝通,不直接與特殊化
類別耦合,而這就是一種因應變動性的設計考量。
總歸上述 2,3 點,其目的就是讓「各類型的物件責任更明確,所擔負的行為更單一
(atomic)」。這在軟體工程來說,即是「高內聚性 (high cohesion)」的展現。
--------------------------------------------------------------------------------------------------
以上這些觀念確實為所謂物件導向分析/設計/實作 (OOA/OOD/OOP)基本功夫。主要目的是
「Design for Change」,卻非是全然針對實作面「寫出來」就好的議題。
這裡就要能著實體會,OOP 所展現的程式碼特質是強調「分散」,而非「集中」,也就是
讓主要類型的物件有明確的責任 (responsibility, knowing/doing)。
試想想,原來可能只是把「計算訂購總額()」的邏輯全給寫在同一支程式碼 (集中),但
物件導向的作法卻很可能會把每一種的計算訂購邏輯 (如考量 bonus/coupon/special
discount),從原來可能用 switch-case/if-then-else 的寫法抽離至多個 sub-class上
,造成分散的效果。
一支程式碼 (single-class)被拆解為多支程式碼 (multiple-class),這對一般軟體開發
人員 (尤其是入行沒多久較在乎能否寫出來的新手)而言,心態上是不容易接受的,更何
況會覺得這樣更難 Debug?!
所以這類分散式特質的程式,比較會應用於大型善變化的系統,例如電子商務平台、ERP
、MIS,而產品設計的態度更是需要。所取得的回饋是讓系統較有度的維護性、彈性與延
展性。其實個人更寧願說:「創造系統高度的再利用價值」,這比較實在。
當然,分散式系統必須伴隨兩種配套:撰寫單元測試程式 (unit-test code),以及持續
重構 (re-factoring)的態度。
分散式系統不會是一開始就能保障設計得很精確、一開始就是分散,那是一種持續重整的
過程與態度。但在重整/重構的過程中,如何確保已上線的功能不會被影響?當然在每一
次的修改前/後,都要跑過單元測試,那才有可能去調整修改程式碼的。
** 可以至 FB 「軟體設計鮮思維」社群內的檔案區,下載關於「物件導向基礎觀念」
的簡報,同時也有提供 C#.NET/Java 程式碼的範例。另外也有其它關於軟體設計相關的
案例 (C#.NET/Java 與 UML Model)可以下載參考。
https://www.facebook.com/groups/softthinking/
--
FB社團:軟體設計鮮思維
https://www.facebook.com/groups/softthinking/
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.34.122.227
※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1510560382.A.6E9.html
推
11/13 16:17,
8年前
, 1F
11/13 16:17, 1F
推
11/13 17:20,
8年前
, 2F
11/13 17:20, 2F
→
11/13 17:20,
8年前
, 3F
11/13 17:20, 3F
→
11/13 17:22,
8年前
, 4F
11/13 17:22, 4F
推
11/13 17:35,
8年前
, 5F
11/13 17:35, 5F
推
11/13 17:45,
8年前
, 6F
11/13 17:45, 6F
→
11/13 17:46,
8年前
, 7F
11/13 17:46, 7F
推
11/13 18:09,
8年前
, 8F
11/13 18:09, 8F
推
11/13 18:31,
8年前
, 9F
11/13 18:31, 9F
推
11/13 18:42,
8年前
, 10F
11/13 18:42, 10F
→
11/13 18:45,
8年前
, 11F
11/13 18:45, 11F
噓
11/13 19:18,
8年前
, 12F
11/13 19:18, 12F
噓
11/13 19:20,
8年前
, 13F
11/13 19:20, 13F
噓
11/13 19:23,
8年前
, 14F
11/13 19:23, 14F
推
11/13 19:30,
8年前
, 15F
11/13 19:30, 15F
→
11/13 19:30,
8年前
, 16F
11/13 19:30, 16F
推
11/13 19:50,
8年前
, 17F
11/13 19:50, 17F
→
11/13 19:55,
8年前
, 18F
11/13 19:55, 18F
→
11/13 19:57,
8年前
, 19F
11/13 19:57, 19F
→
11/13 19:57,
8年前
, 20F
11/13 19:57, 20F
推
11/13 20:10,
8年前
, 21F
11/13 20:10, 21F
→
11/13 20:10,
8年前
, 22F
11/13 20:10, 22F
→
11/13 20:16,
8年前
, 23F
11/13 20:16, 23F
→
11/13 20:20,
8年前
, 24F
11/13 20:20, 24F
推
11/13 20:38,
8年前
, 25F
11/13 20:38, 25F
→
11/13 20:38,
8年前
, 26F
11/13 20:38, 26F
推
11/13 21:09,
8年前
, 27F
11/13 21:09, 27F
→
11/13 22:42,
8年前
, 28F
11/13 22:42, 28F
推
11/13 22:45,
8年前
, 29F
11/13 22:45, 29F
→
11/13 22:46,
8年前
, 30F
11/13 22:46, 30F
→
11/13 22:51,
8年前
, 31F
11/13 22:51, 31F
推
11/13 22:53,
8年前
, 32F
11/13 22:53, 32F
→
11/13 22:54,
8年前
, 33F
11/13 22:54, 33F
→
11/13 22:55,
8年前
, 34F
11/13 22:55, 34F
推
11/13 23:28,
8年前
, 35F
11/13 23:28, 35F
→
11/13 23:54,
8年前
, 36F
11/13 23:54, 36F
推
11/14 02:12,
8年前
, 37F
11/14 02:12, 37F
推
11/14 06:03,
8年前
, 38F
11/14 06:03, 38F
→
11/14 06:03,
8年前
, 39F
11/14 06:03, 39F
→
11/14 08:09,
8年前
, 40F
11/14 08:09, 40F
推
11/14 09:15,
8年前
, 41F
11/14 09:15, 41F
→
11/14 09:16,
8年前
, 42F
11/14 09:16, 42F
推
11/14 10:36,
8年前
, 43F
11/14 10:36, 43F
→
11/14 10:36,
8年前
, 44F
11/14 10:36, 44F
推
11/14 11:33,
8年前
, 45F
11/14 11:33, 45F
推
11/14 13:15,
8年前
, 46F
11/14 13:15, 46F
推
11/14 14:05,
8年前
, 47F
11/14 14:05, 47F
→
11/14 17:09,
8年前
, 48F
11/14 17:09, 48F
噓
11/16 12:38,
8年前
, 49F
11/16 12:38, 49F
推
05/15 15:08,
8年前
, 50F
05/15 15:08, 50F
討論串 (同標題文章)
Soft_Job 近期熱門文章
PTT職涯區 即時熱門文章
769
1488
80
120