※ 引述《hsnucsc (hsnugo)》之銘言:
: 我找了很多網站
: 都將解釋SRP成: 每一個物件, 應該要只有單一的responsibility
: 而將responsibility解釋成: 只有一個理由去改變物件
: 但是我還是覺得responsibility這個詞很模糊
: (如果直接翻譯成中文, "責任", 仍然很難知道這個責任的大小)
: 以書上的例子而言
: Automobile 車子有很多功能
: start()
: stop()
: changeTiles(Tile [*])
: drive()
: wash()
: checkOil()
: getOil()
: 應該要被分解成
: Automobile
: start()
: stop()
: getOil()
: Driver
: drive(Automobile)
: Carwash
: wash()
: Mechanic
: changeTires(Automobile, Tire[*])
: checkOil(Automible)
: 有一些method移交到其他物件處理
[恕刪]
: 不過仍然讓人很難分辨responsibility
: 說嚴格一點, 好像每個method, 都有理由改變
: 但是又不可能把每個method都新增一個物件去處理這項功能
: 希望有人可以幫忙解答
: 謝謝
弟剛好看到同一本書了,雖然這討論已經有一陣子了。
我想試著把書上較完整的說法寫下來。
最初 Automobile 類別含有下列功能:
class Automobile {
public void start();
public void stop();
public void changeTires(Tire[] tires);
public void drive();
public void wash();
public void checkOil();
public int getOil();
}
書上說 (深入淺出軟體開發 中文版 P156)
大多數的時間,你可以利用簡單的測試,找出未使用 SRP 的類別:
1. 在一張紙上,寫下幾行像這樣的東西:
The [ ] [ ] itself。
對你正在測試 SRP 的類別裡的每一個方法,
你應該有一行像這樣的東西。
2. 在每一行的第一個空格裡,寫下類別名稱;
在第二個空格裡,寫下類別的方法之一。
3. 大聲把每一行讀出來(你可能得加一點字才會好唸)。
你所唸出來的東西合理嗎?
你的類別真的具有該方法所指的責任嗎?
萬一你所出來的東西不合理,你的方法可能違反 SRP。
該方法很可能屬於別的類別...考慮移掉它吧。
==================================================
SRP 分析: Automobile
The Automobile start[s] itself.
The Automobile stop[s] itself.
(汽車負責啟動與停止,很合理,那是汽車的功能。)
The Automobile changesTires itself.
(汽車不負責自己換輪貽)
The Automobile drive[s] itself.
(
這一個有點弔詭...我們認為雖然可以啟動與停止它自己,
但駕汽車實際上是駕駛人的責任。
)
The Automobile wash[es] itself
The Automobile check[s] oil itself.
(汽車不負責自己清洗自己,或自己換機油。)
The Automobile get[s] oil itself.
(汽車能傳回剩餘油量)
==================================================
我覺得書上提供的方量很簡單易用,
至少比起直接看 SRP 的定義,
用初學者較無系統化地步驟去思索:
"哪些功能在類別內可能是被錯置的?",來得有效率。
確實每個 method 都可能存在改變的理由,
但在明辨出"單一責任"區後,只為負責任而改變。
事情會單純許多,一但類別承擔較多的責任,
那改變的理由、機率就相對增加了不是嗎 :)