邁向熟手之路 - 物件導向程式設計

閱讀時間約 6 分鐘


在上一篇文章我們有聊到過程式設計的三個基本要素,循序、選擇、迴圈。只要掌握這三個觀念,不管你用哪種程式語言你都能很好的基礎入門。我自己經過這麼多年的觀察與實踐,一個成熟的軟體工程師還需要第四個要素「物件導向程式設計」,它是讓決定你通往熟手的重要關鍵沒有之一。

物件導向程式設計

早期我們學程式設計的時候都是使用 「功能分解」 的觀點來構建程式,所謂的功能分解就是把業務流程的每一個動作按照先後順序全部拆解出來,也就是以「萬物皆動作」的觀念來設計程式。具體的狀況是先畫好流程圖後再開始 coding ,流程圖內會標示起點到終點,主程式從頭到尾負責所有動作是一個不可分割的整體。

物件導向程式設計採取的策略是改用「萬物皆物件」的觀點來寫程式,跟功能分解最大的差異是把的業務流程按照責任分工拆解出不同任務需求的角色物件,靠物件間的互動關係來設計程式,工具上改用 UML 來表達程式裡面的物件繼承架構與互動關係,分而治之可謂是物件導向設計的核心。

分而治之是物件導向設計的核心。


好的封裝從觀察開始

要進入物件導向設計須要從封裝開始。關於封裝,通常程式設計書大概會這樣描述:

把一個或多個 data 跟 method 放進一個 class 裡面

這是單純從程式語言的角度、從字面上最直接的解釋,精準但幫助有限。因為要如何選擇哪些 data 跟 method 放在一起取決於你要解決的問題,作者只能站在教學的立場嘗試給出一些通則範例,不是太過簡單就是通常都離你的問題很遠,所以學習階段不用過度糾結。

不需要糾結遠離問題核心的範例

我們真正要做的是借用封裝的原則來仔細審視你的問題,嘗試辨識出潛藏裡面的各種物件,找出它們的特性跟能力與彼此該如何互動的關係,分析過程有點像是寫 pseudo code 需要先把想法邏輯整理起來,最後才是去對照你選用的程式語言的語法轉換成 data 跟 method 然後封裝到對應的 class 裡面。只有這種方式定義出來的 class 們才會對你的設計產生意義,實體化出來的物件才有了解決問題的能力。

「仔細審視你的問題,嘗試辨識出潛藏裡面的物件」是站在上帝視角看問題

在小朋友過馬路場景裡面除了小朋友以外,還會有馬路、周邊住家商店、往來的車輛跟交通號誌等”物件”,關鍵”物件”就是我們解決問題過程中必須要辨識出來的對象。我知道有些人鉅細靡遺,觀察的畫面非常豐富,記住一個最小設計原則,只需要把關鍵物件辨識出來然後封裝到所需的類別裡面去就可以了。

運用最小設計原則找出關鍵物件


能見度決定封裝品質

經過仔細觀察分析問題後你已經找出關鍵物件以及它們之間的運作關係,那麼決定封裝品質依據是什麼呢?答案是能見度。

每個封裝進 class 裡面的 data 或 method 特性值都還要加上 private public 等能見度設定。我認為一個好的封裝品質要有最低的能見度,就像封裝手機一樣嚴密結實完全地不透明,只需要提供人機介面來互動即可,使用者並不需要手機裡面的結構、線怎麼 layout 的對使用者來說並不重要也不需要知道,不需要暴露出來。看不到設計細節這點對只習慣功能分解設計的人會需要花時間來適應。習慣後慢慢改變你看事情的觀點,也會發現你的設計變得越來越自然,

手機是品質良好的封裝典範


繼承是體系也是規範

繼承最常被拿來討論的觀點是 Reuse,要是把 Reuse 講成了是繼承的唯一目的就有點狹隘了。相較前面封裝是觀察找出物件,繼承是為了將找出來的物件們進行分類歸納,嘗試找出物件之間共同點來建立新的 class 確認彼此的上下關係練。找出共同點,找出物件共同意義上的集合當作父類別,並依此作為繼承關係的標的。

繼承體系是物件間的上下關係鏈

還是那個小朋友過馬路的例子,上學時間會過馬路的不只是小朋友,而是有國小生、國中生和高中生。此時學生類別就很適合當作它們共同的父類別,當上班族等其它非學生的族群也加入後,就需要的更適合的行人類別 (上班族跟學生族都是行人的子類別) 來當作基礎類別。整理的關鍵就是找出把他們的共同部份抽出來定義成父類別,過程中不斷的利用 「is a, has a」 來確認,最終在你的設計方案裡成為一個完整的繼承體系。

可以被繼承的東西技術上也可以是半實作的抽象類別或是完全不實做的抽象介面來繼承,可以把這種抽象類別或介面想成一組規範或能力,所有的子類別都要實作父類別所指定的能力(或者說,只有完全具備要求能力才屬於這個類別),所以在遊戲軟體設計裡面可以創造出各種非現實的物體,例如會飛行跟噴火能力的烏龜,只要讓那隻烏龜物件繼承並實作了飛行跟噴火的介面就可以了。

抽象類別是規範或能力的組合


多型才是真實應用型態

再回到小朋友過馬路例子,如果使用功能分解的設計,主程式必須完全掌握每一個小朋友的各種特徵與運動能力,還要嚴格規定過馬路的每一個動作,從該站在哪個位置、起步要左腳先還是右腳先、每一步要走多少距離,要用多快速度移動等全部都要主程式來決定,可以做到但與現實不符!

現實中是不可能知道每個小朋友特徵與能力的,此時怎麼辦呢?很簡單,就來觀察小學老師怎麼做。首先老師會先讓要過馬路的小朋友們不分年級全部集合排成一列,使用「同學」稱呼所有的小朋友,透過同學這個介面來下達「同學們開始過馬路」指令,然後每個小朋友收到指令後很自然地用自己的方式就開始過馬路了。

學生與行人都會自己過馬路

老師使用「同學」的方式來控制各種不同小朋友個體的方法就是多型應用,負責控制流程的老師並不需要知道隊伍裡面的每個小朋友個體狀況,所有的同學都有過馬路的能力,而小朋友們都是這個類別的實體,自然都具備自己過馬路的能力,而在主程式裡面使用多型設計才是我們使用繼承的真正目的。

多型應用才是繼承的真正目的


小結

好了,講完啦。是不是感覺物件導向的觀念還是有點很困難且複雜?!確實物件導向設計的門檻很高,但也具備更好的投資價值。學會物件導向設計觀點後自然會更注重整體架構、物件完整性還要顧慮彼此互動關係,當然設計過程也會充滿挑戰性,特別是你的邏輯推演、歸納物件、概念抽象化的能力。

還有 UML 也是物件導向設計必備的工具,特別是再跟團隊合作的時候特別有感。進化過程需要時間且辛苦的,當你真正學會用「萬物皆物件」的觀點就能設計出「最自然且符合人性」的程式,你的程式運作起來會更貼近真實的世界。附帶的好處還有實現分而治之的高內聚、低耦合的設計,也會讓你的程式規模可以更大又更好維護。最後,再把眼光放遠一點,將來還有機會繼續升級到更高階的設計模式,真正進入架構設計領域了。

12會員
60Content count
WarrenLo's 軟體設計武功祕笈
留言0
查看全部
發表第一個留言支持創作者!
Warren Lo的沙龍 的其他內容
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...
當這產品的這個 API 被呼叫,再從回傳內容的某個欄位欄位來判斷,只要“這個欄位”顯示 false 就代表不支援」,雖然這樣的設計也能滿足功能需求…
關於程式語言的學習,只要掌握住幾個基本特性要熟悉幾種程式語言也不困難,這三個基本特性就是…
IDE 升級後出現了一樣的錯誤,手上程式碼沒有 pylint black-format 檢查上不了 gitlab,我又點開了那個很小很小的 x 符號,裡面 logs 提示的解決方式是升級..
在網路上查找可以發現有很多類別圖的 6 種關係的說明與示例,通常不太容易難取得共鳴。主要有兩個原因: 1. 對於這些關係線的定義混淆,導致無法判斷滿足條件與使用時機 2. 缺少生活相關的具體案例,很難理解這些關係所對應的抽象概念
UART 轉換完成的 Serial 訊號已經可以用來傳輸通訊了,那為什麼還要把 UART 轉出來的訊號再轉換成成其他的 Serial 介面,像是 RS232/RS485 再進行傳輸呢?原因是 UART 的 Serial 訊號傳輸的距離實在太短了
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...
當這產品的這個 API 被呼叫,再從回傳內容的某個欄位欄位來判斷,只要“這個欄位”顯示 false 就代表不支援」,雖然這樣的設計也能滿足功能需求…
關於程式語言的學習,只要掌握住幾個基本特性要熟悉幾種程式語言也不困難,這三個基本特性就是…
IDE 升級後出現了一樣的錯誤,手上程式碼沒有 pylint black-format 檢查上不了 gitlab,我又點開了那個很小很小的 x 符號,裡面 logs 提示的解決方式是升級..
在網路上查找可以發現有很多類別圖的 6 種關係的說明與示例,通常不太容易難取得共鳴。主要有兩個原因: 1. 對於這些關係線的定義混淆,導致無法判斷滿足條件與使用時機 2. 缺少生活相關的具體案例,很難理解這些關係所對應的抽象概念
UART 轉換完成的 Serial 訊號已經可以用來傳輸通訊了,那為什麼還要把 UART 轉出來的訊號再轉換成成其他的 Serial 介面,像是 RS232/RS485 再進行傳輸呢?原因是 UART 的 Serial 訊號傳輸的距離實在太短了
你可能也想看
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
去年底,孫女出生,回家之後,我對她都講台語,對女兒也講台語,女兒小時候跟阿公在一起,台語大都聽得懂,不懂的會問我,有的詞我會主動再說一遍華語,有時候她會回我台語,就這麼慢慢浸淫其中,不管小孩或大人,多會一種語言,就多一項寶藏,雙語不是只有增加英語一種,台語、各種母語也算。 一、 2個女兒和兒子時
Thumbnail
我漸漸不再滿足於撰寫單篇的文章,而期待自己能有系統的整理這些內容,越寫越長的文章,越來越多的內容,回憶起來在這個時期,臉書提供的環境已經不再適合我。
Thumbnail
雖然決定要把文章跟讀者帶到新平台,但臉書不給面子,讀者不買帳,身為創作者又該如何自處?
Thumbnail
回顧從2017年開始的東京裏物語到底做了些什麼?寫了些什麼?
Thumbnail
作為組織,我們到底要怎麼運作?作為興趣我們又該付出多少?又是一個大哉問。
Thumbnail
已經知道自己的內容受眾是小眾時該怎麼自處?又該怎麼調整將來方向呢?
Thumbnail
「如果內容有價,我的讀者願意付出多少?」這題對創作者來說是個殘酷的問題,而放棄受眾,而轉向廠商收錢的創作者也大有人在,加入了金錢,我們跟受眾的關係究竟會怎麼變化呢?
Thumbnail
從2017年開始的專頁,現在在演算法的挑戰下,面臨了換平台的難題。這系列文章是我作為總編,對換平台一事的思考歷程所留下的筆記。
Thumbnail
人生真是一段奇妙的星球之旅,充滿了各式各樣驚喜與事物等著我們去體驗。 就在正式提出辭呈後,覺得那壓抑許久的心終於豁然開朗起來。 先來回顧一下我之前做過的工作和經歷: 19歲以前的打工簡單說一下有水果攤、7-11清潔工(竟然比店員高薪)、廚師助理...大致上就這些。 19歲後的這些大致上都是正職
Thumbnail
根據台灣證券交易所統計,在2019與2020年短短一年間,開戶人數約增加120萬人,相較於過去十年每年增加之開戶人數,整整差距近乎兩倍。不僅是在開戶人數的增加,年齡層20至30歲交易占比之增加幅度更大於其他年齡層,顯示近年除了參與台股投資人數增加外,年齡層也有年輕化之趨勢。
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
去年底,孫女出生,回家之後,我對她都講台語,對女兒也講台語,女兒小時候跟阿公在一起,台語大都聽得懂,不懂的會問我,有的詞我會主動再說一遍華語,有時候她會回我台語,就這麼慢慢浸淫其中,不管小孩或大人,多會一種語言,就多一項寶藏,雙語不是只有增加英語一種,台語、各種母語也算。 一、 2個女兒和兒子時
Thumbnail
我漸漸不再滿足於撰寫單篇的文章,而期待自己能有系統的整理這些內容,越寫越長的文章,越來越多的內容,回憶起來在這個時期,臉書提供的環境已經不再適合我。
Thumbnail
雖然決定要把文章跟讀者帶到新平台,但臉書不給面子,讀者不買帳,身為創作者又該如何自處?
Thumbnail
回顧從2017年開始的東京裏物語到底做了些什麼?寫了些什麼?
Thumbnail
作為組織,我們到底要怎麼運作?作為興趣我們又該付出多少?又是一個大哉問。
Thumbnail
已經知道自己的內容受眾是小眾時該怎麼自處?又該怎麼調整將來方向呢?
Thumbnail
「如果內容有價,我的讀者願意付出多少?」這題對創作者來說是個殘酷的問題,而放棄受眾,而轉向廠商收錢的創作者也大有人在,加入了金錢,我們跟受眾的關係究竟會怎麼變化呢?
Thumbnail
從2017年開始的專頁,現在在演算法的挑戰下,面臨了換平台的難題。這系列文章是我作為總編,對換平台一事的思考歷程所留下的筆記。
Thumbnail
人生真是一段奇妙的星球之旅,充滿了各式各樣驚喜與事物等著我們去體驗。 就在正式提出辭呈後,覺得那壓抑許久的心終於豁然開朗起來。 先來回顧一下我之前做過的工作和經歷: 19歲以前的打工簡單說一下有水果攤、7-11清潔工(竟然比店員高薪)、廚師助理...大致上就這些。 19歲後的這些大致上都是正職
Thumbnail
根據台灣證券交易所統計,在2019與2020年短短一年間,開戶人數約增加120萬人,相較於過去十年每年增加之開戶人數,整整差距近乎兩倍。不僅是在開戶人數的增加,年齡層20至30歲交易占比之增加幅度更大於其他年齡層,顯示近年除了參與台股投資人數增加外,年齡層也有年輕化之趨勢。