[OOD] 為什麼單一職責原則(SRP)是最難運用的

Horky發表於2015-04-18
單一職責原則(SRP)已經幾乎是每一個程式設計師都知道的設計原則。最早由Robert C. Martin在<<敏捷軟體開發 — 原則、模式與實踐>>中正式提出。書中作者在結論中提到:
  SRP是所有設計原則最簡單的,但也是最難運用的。(中文翻譯有之一,略去了)

現實工作中,關於一個類是否符合SRP,或者是否有必要符合SRP的討論是經常發生的。爭論的關鍵在於職責的定義,但我理解SRP真正的核心是關注於變化。這並不是我的新見解,全是來自Martin大叔的解釋:
  1. 首先職責的定義是: 引起變化的原因,不是由分類所決定的。如果存在相對的變化,才要考慮分離。
  2. 其次,關於引起變化的因素,不要空想。一定確信有變化的可能,才會加以考慮。

他的提醒是非常中肯的。實踐中正是常常基於功能的分類來定義職責的。


舉個例子。假如我們要開發一個學校的教職員工管理系統。需要定義一個教師員工的類(炒菜的師傅先就不考慮了),考慮到老師和班主任兩個角色,通常會認為他有兩類職責:
  . 教師 (班主任很可能會帶課)
  . 班級的管理 (組織班委,整治一下早戀之類的)


這時你拿著設計到了一個寄宿學校,校長可能會告訴你,他們這裡的教師會輪流值班,兼做保育員,照看住校的學生。又是一個新的職責,怎麼辦?

如果遵守單一職責的原則,我們應該增加一個介面:


果真要如此嗎? 注意,如果是在一般的學校,保育員不是老師的本職工作,可在這所寄宿學校裡,卻是教師的本職工作,是和老師一起變化的。校長的反饋是: 

 “我們學校的教師必須擔任保育工作,我並不認為這會是什麼新職責。作為教師,要麼接受,要麼離開。至於班主任工作,確實還是其特殊的地方,不然也不會給擔任班主任的老師多一點津貼了。”。


請再體會一下,關於保育員職責的討論。如果兩個職責/角色不是同時變化的,才考慮分離。如果確定同時變化,就沒有必要分離。除非有一天,某個勞動部門到該寄宿學校檢查,認為他們這樣不符合某個法律規定,強制規定老師可以選擇是否擔當保育員。如此一來,兩個職責就又變成獨立變化的了,就可以考慮分離職責。

再進一步,如果是針對一個只有一個支教教師的小學,極為偏僻。這裡的校長會告訴你:

   ”這個學校裡的每一個教師,唯一的一個,既是校長,也是老師。我不認為還需要明確班主任做什麼,教師做什麼,在這裡,只要學生需要的都要做。並且這裡很窮,五年內都不見得再有新老師來。”。


這個感人的故事告訴我們,在這所學校裡, 他不在了,這所學校也就不在了,完全沒有什麼相對的變化,也沒有什麼可以確認的變化。所以在這裡的管理系統裡,教職員工只有一個單例項類,:

(向朱敏才孫麗娜夫婦致敬!)

聊到這裡,不知道我說清楚了沒有!設計要跟著需求走,不能生硬的套理論。歡迎拍磚!

相關文章