因為工作上的需要,因此,我特別安排時間來進行 SOLID OOD 物件導向程式設計的研究與學習,我想,我應該是與大家一樣,開始都是從 Google 上來搜尋 SOLID SRP OCP LSP ISP DIP Principle 等關鍵字,看看網路上的人怎麼說,也須我的資質不好,搜尋到一大票的文章,怎麼看,怎麼不懂,最重要的是,當我好不容易看懂,例如 Single Responsibility Principle SRP ,接著看到更多的文章所說明的內容、圖片、解釋、範例,就更加的模糊與不清楚他到底是要做甚麼用到、可以幫助我做甚麼事情、我該如何將我的程式碼撰寫或重構成具有 SRP 精神的程式碼,這也包括了不同作者所舉例的程式碼,並不是我孰悉的 C#,這讓我在閱讀那些程式碼的過程中,也是備感艱辛;過程中,我也產生了許多的疑問,再次以 SRP 為例,為什麼每個文章作者,對於所舉例的範例程式碼,緊接著就說這段程式碼具有三個責任,所以,我們要把這三個責任進行分離開,我的老天鵝呀,我是真的不知道為什麼是三個責任,不是兩個,也不是五個。
好吧,既然廣泛涉獵的許多網路上的 SOLID 的文章,那麼,只好痛下決心,花點索費,到 Amazon 去買 Uncle Bob 寫的兩本書來看看 (會去買 Uncle Bob 的書,這是因為 SOLID 是 Uncle Bob 根據不同人提出的分享,綜合出這五個原則) ,也花了點時間,找出 Uncle Bob 當初所提出的 SOLID 五篇文章,既然東西都到手之,就要開始花點時間把這些最初的資料給他閱讀一番。不過,最後,我還是想辦法把當初提出這些原則人寫的文章、書,也給他購買或者找出來,並且從中細細體味出箇中奧妙之所在。
因此,對於想要把 SOLID 弄清楚的人,在此提出幾個建議
OOP 物件導向程式設計
若您對於 OOP 的四個特性不慎了解,甚至沒有研究過 OOP 四個特性,我覺得您應該要先去了解與孰悉 OOP 的四個特性:抽象、封裝、繼承、多型
弄清楚這些名詞的意義
當您在進行 SOLID 學習過程中,需要處處存著兒時好奇心態,保持您的疑問,雖然,當時您可能無法理解或明瞭其中含意,不過,這對於您日後學習上,會有著明顯的好處;若平常都有做善事,有著好機緣,碰到真正會的有緣人(千萬不要去問自以為是,處處都是我認為、我想的、我平常都是這樣做的的人去問,這樣,您會走火入魔的),把你蒐集起來的問題,向他們請教看看。
首先,您需要了解 甚麼事 Principle 原則,因為, SOLID 是由五個 Principle 所組成,若您不瞭解何謂 Principle 的意義,那麼,就算您學會了這五個 Principle,您覺得對你會有甚麼幫助呢?
緊接著,要把每個原則的每個英文字與其解釋(我是參考 Uncle Bob書中對於這五個原則的描述),挑出主要的名詞,了解他們存在的意義與目的 (千萬不要使用您本身所學的經歷來看待這些名詞,畢竟,這些原則是早在 20 年前所提出來的,那個時候,可是沒有 C# / Java 這樣的語言存在,還是那句話,不要憑感覺來認為自己就是一切),這樣會有助於您去閱讀書中、文章中之各原則的論述。
SRP Single Responsibility Principle 單一責任原則
A class should have only one reason to change
請了解甚麼事個 Responsibility 責任,不過,在其他文章中,您可能會看到有些內容會使用 Module 模組來取代 Class 類別,您可以嘗試體會與思考看看,為什麼會有 Module 這個名詞出現,這會對於您之後學習過程中有莫大的幫助;另外,也需要甚麼是 Change 變更需求,為什麼會有它,他會造成甚麼影響,如何改善因為 Change 所產生出來的問題。總之,凡事抱著疑問來學習。
OCP Open Closed Principle 開放封閉原則
Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification
OCP 開放封閉原則,是我們進行專案開發過程中,最為重要與經常會面對的問題,所以,務必要花些時間來精通才好。
在這裡,請要了解這些詞彙的意義與精神: Open / Closed / Software Entity / Extension / Modification 。對於後面兩者,請要去了解,就是目標對象指的是誰,也就是誰要開放,誰要封閉,究竟怎麼開放,怎麼封閉。
在您觀看 OCP 內容的時候,會看到很多文章舉的例子,都是使用 Interface 介面,來做為重構成為符合 OCP 的作法,請千萬不要畫地自限,以為,想要符合 OCP 的精神,就只能使用 介面 來解決,有興趣的人,可以去嘗試看看,要做出符合 OCP 精神的程式碼,至少有六七種以上的技術可以做到。
LSP Liskov Substitution Principle 里氏替換原則
Subtypes must be substitutable for their base types
這個原則主要的重點就是替換這個名詞,您也許會覺得很奇怪,這到底是甚麼原則,為什麼要放在 SOLID 這五個原則內,他有甚麼重要性?在想要了解這個原則,您應該要先從他的背景來研究,那就是 OOP 裡面的繼承與多型,也就是說,若您對於這兩個名詞也一知半解,那麼,這個原則所提到的內容,您是無法體會出來的。
ISP Interface Segregation Principle 介面隔離原則
Clients should not be forced to depend upon interfaces that they don't use
這也是個大家覺得好莫名的原則,介面與隔離,是這個原則要探討的重點,還是那句話,若您在開發程式設計過程中,幾乎沒有自己設計過介面,或者不太了解介面的應用與特色,那麼,您會學得很辛苦;另外,就是一個問題,為什麼會產生一個具有那麼多方法宣告的介面,也許,您會說:要是我自己開發,就不會有這樣的問題?可是,請不要用自己的經歷、角度來看這些原則,在一個專案開發與設計過程中,往往會有多人一起進行開發,當然,任何人都可以去修改介面的宣告,所以,您應該已經知道為什麼會產生一個超級胖的介面了。因此,了解這樣的介面會產生的副作用,並且規避這樣的現象產生,也就是這個原則的精神了。
DIP Dependency Inversion Principle 相依反轉原則
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions
這個原則需要用到兩句話來說明,因此,我們需要了解這兩句話中的各個腳色與扮演目的:高階模組、低階模組、模組、抽象、明細、相依。喔喔,這五個原則中,看樣子是這個原則中出現了最多的名詞,我個人覺得最重要的詞彙就是 相依 Dependency ,了解何謂相依、為什麼會相依、相依會造成甚麼樣的問題、怎樣才是一個好的相依,這樣,也許您就已經對於這個原則了解一半了。不過,若您的程式設計與開發生涯中,幾乎沒有用到過或者很少用到過相依性注入這樣的設計模式,那麼,您可能無法深刻體會出這個原則想要幫您解決甚麼問題。
打通任都二脈
若您經過研究,有了解與孰悉 OOP,對於這五個原則的各個用到的詞彙也明瞭,甚至有看過這五個原則當初的背景文章,而且也看過各種原則的範例程式碼,那麼,您已經完成了第一步,接下來,您將會需要
- 找出與練習撰寫出 違反原則的程式碼,自己嘗試重構這個程式碼,使其符合原則
- 嘗試自行分析,若一個程式碼,符合 OCP,是否就符合 LSP,反過來說,符合 LSP ,是否就是符合 OCP;另外一個是,若程式碼符合 OCP,是否就符合 DIP,反過來說,符合 DIP ,是否就是符合 OCP,嘗試挑戰看看這樣的論述是否都是為真,還是不是,若不是,您可以舉出這樣的例子呢?
關於 Xamarin 在台灣的學習技術資源
歡迎加入 Xamarin 實驗室 粉絲團,在這裡,將會經常性的貼出各種關於 Xamarin / Visual Studio / .NET 的相關消息、文章、技術開發等文件,讓您可以隨時掌握第一手的 Xamarin 方面消息。
歡迎加入 Xamarin.Forms @ Taiwan,這是台灣的 Xamarin User Group,若您有任何關於 Xamarin / Visual Studio / .NET 上的問題,都可以在這裡來與各方高手來進行討論、交流。
Xamarin 實驗室 部落格 是作者本身的部落格,這個部落格將會專注於 Xamarin 之跨平台 (Android / iOS / UWP) 方面的各類開技術探討、研究與分享的文章,最重要的是,它是全繁體中文。
Xamarin.Forms 系列課程 想要快速進入到 Xamarin.Forms 的開發領域,學會各種 Xamarin.Forms 跨平台開發技術,例如:MVVM、Prism、Data Binding、各種 頁面 Page / 版面配置 Layout / 控制項 Control 的用法等等,千萬不要錯過這些 Xamarin.Forms 課程