Single Responsibility Principle 單一職責原則
從原則的名稱很容易就可以得出該原則需要做的事情——物件只擁有/負責某一個責任。
怎麼樣才是擁有/負責一個責任呢?
🌰(例子):
- 我們設計某個類別只負責會員的邏輯。
- 會員可以進行下單的動作,那麼下單邏輯則可以放在該類別中
- 會員無法刪除他人的評論,那麼刪除他人評論的邏輯,就不可實作在該類別中。
- 遊戲中設計劍的邏輯:
- 若是仙劍等玄幻遊戲的話,可能需要加入飛行的能力。
- 若是其他現實類遊戲的話,可能不需要飛行的能力,就不應該實作在該類別中。
- 劍可以釋放技能,只是每把劍的技能不同,所以上層類別只需要知道劍能釋放技能,而技能的效果只需要劍自行實作即可。
從上面幾個🌰可以看到,我們需要先定義出某些類別的能力,然後再來實作它。
只要不超出定義的範圍,那麼無論實作多少種類別,對於使用到定義類別的上層類別的影響都不會太大。
網路上看到一句話: program to an interface, not an implement
我們定義好類別的能力,也就是定義出了一個抽象(abstract)/介面(interface)。
每一個不一樣的會員/劍,只要實作它們自己的細節,實際動作的方法,不實作額外的事情,就符合單一職責原則。
這個原則其實也能套用到現實世界中也適用喔~
- 公司找程式人員時,不是找某個類別的人,而是只找有實作程式能力的人。
- 那麼只需要來應徵的人有自己實現寫程式的介面即可,公司不會理會你有沒有飛行執照,公司注意的是你的寫程式介面。
- 駕駛車子的方法。
- 駕駛車子只需要駕駛員有實現駕駛的能力(
考到駕照) - 可能某些殘障人士駕駛的車子需要做一些改裝後,殘障人士才能駕駛,那麼這時候“駕駛”這個介面就需要定義2種。
- 駕駛車子只需要駕駛員有實現駕駛的能力(
依照該原則實作程式的特點有:
- 各個類別的責任/邏輯解耦(decoupling)。
- 類別只負責自己的實作,只要其定義沒有修改,就不需要修改實作,穩定性UP。
- 每個類別有自己的邏輯/責任,修改其他類別後,類別間的影響不大,穩定性UP UP。
程式範例
參考: https://github.com/exia56/player-training2
該程式只是模擬個簡單的開發流程,以及簡單的程式碼。
在我寫的參考程式中,我只有基本定義2個介面——player與playlist。
1 | //~/modal/player/iPlayer.cs |
我定義了player可以播放、暫停、停止、初始化等。
只要player的定義不更改,那麼實作player介面的類別都不需要修改。
對於上層類別(Program),他只需要知道我們使用的類別一定會實作IPlayer介面就好,內容實作了什麼程式都不重要(VLC or WMP)。
1 | // ~/modal/playlistEnumerable.cs |
playlist的部分則是只定義了取得下一個播放文件的功能。
我們也可以在接下來的版本定義playlist的功能有增加影片、修改播放順序、刪除影片等功能。(小夥伴們可以自己想想能怎麼做吧~
Program類別使用到了player與playlist介面,那麼相對來說:
- Program相對於player與playlist是上層類別。
- player與playlist相對於Program是下層類別。
Program作為上層類別,只需要知道各個介面的能力即可,不需要知道實作介面的類別的細節。
而下層類別的player與playlist則只需要處理好自己以及自己的下層類別就好了~
總結
我們定義好類別的能力,也就是定義出了一個抽象(abstract)/介面(interface),再來以該抽象/介面來實作就好了喔。
話說。。。介紹完這個原則後,我發現SOLID的東西其實已經解釋了7成了,剩下的只是沒有說清楚講明白而已。
接下來幾篇文章就再繼續補充好了,反正總結起來,就是下面這句話的體現了。
program to an interface, not an implement
知識鏈結
搞笑談工程: http://teddy-chen-tw.blogspot.com/2014/04/solid.html