※ 引述《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 都可能存在改变的理由,
但在明辨出"单一责任"区后,只为负责任而改变。
事情会单纯许多,一但类别承担较多的责任,
那改变的理由、机率就相对增加了不是吗 :)