好的OO設計原則,可以達到高內聚低耦合的目的,
而什麼是好的設計原則呢? 就是SOLID原則,剛好是由五個(也有人稱六個)原則的首字母組成的縮寫,SOLID也就是穩固的意思。遵守這些原則,可以讓我們的設計更加穩固,更能擁抱變化。
今天這一篇,先介紹單一職責原則,也就是Single Responsibility Principle,簡稱SRP。
Single Responsibility Principle,簡稱SRP
1.定義
應該有,且只有一個原因,會引起class的變更。
原文解釋:There should never be more than one reason for a class to change.
2.備受爭議的原則
這是一個備受爭議的原則,因為要完全做到幾乎是不可能的。但那是實作上的權衡取捨,基本上它還是一個好的設計原則,只單純在實作上備受爭議,在設計上這才是OO的細度到了極致的境界。
3.簡單的說
一個class只負責一個職責的內容。
一個class如果要負責多個職責,其內容應該只是組合多個class,而每個被組合的class只負責單一職責,且通常這樣的組合都是透過接口(interface/abstract)。
4.單一職責的好處
(1)class複雜性降低,因為實現什麼職責都有很清楚的定義
(2)可讀性提高
(3)可維護性提高
(4)變更引起的風險降低,變更範圍降低,擴展性提高
單一職責,也就是高內聚力的實作方式。
5.實作上最困難的地方
原則很簡單,但實作上為何困難? 最難的就是定義所謂的『職責』,以及切割class的粒度取捨。
太細,就剁的太碎,失去實際應用上的目的。例如前一篇文章講的樂高積木,我們要的,應該是每一個單位小到我想要組合成任何模型,都不會有本質上的困難。
細到無窮止盡,可能就是原子的世界了,每一個人看原子,都不知道最後組出來會是長什麼樣子,更遑論應用它了。
6.取捨平衡點
至少要做到interface的單一職責!
7.舉例
我們定義一個電話功能的interface
public interface IPhone{
public void dial(String phoneNumber);
public void chat(Object o);
public void hangUp();
}
這是頗常見的interface定義方式,但dial與hangUp其實應該是同一職責,而chat是另一個職責才對。所以我們應該是Phone要實作這兩個職責的interface。
如此一來,不論未來在修改或擴充電話的功能,都會更加清楚與獨立。
這~OO的原則.
但Object對不同的人或角色有不同的定義.
對於手機使用者.這三個方法可能視為一個手機個體.
但對於手機製造商,他們可能視為不同的個體.
東西不是設計的越細或越粗就越好.
是要對Client有意義才是好的設計.
像樂高也是一樣.
對於小朋友,以一個車燈構造的積木而言是沒意義的,他要以一輛車的積木組為單位設計及販售.
對於高階玩家,一個車燈對他來說非常有意義,因為他可以買很多小積木(元件),去組成一台機器人.