2007
年
3
月
22
日星期四
?
第四
章
責任
責任是什么
雖然作者在第一章就介紹了責任,然而在這一章作為對責任的單獨論述,給出了關于責任更加詳細的說明:責任是關于軟件對象的一般聲明,它們主要包括以下
3
個方面:
l????????
對象執行的動作。
l????????
對象持有的信息。
l????????
能夠影響到其他對象的決定。
以下內容位于第
117
頁
維護信息的責任意味著:
l????????
對象直接持有信息(作為對象的屬性)
l????????
可以從其他地方獲得信息
l????????
當被請求時,它可以與協作者共同完成任務并且返回信息(負責將結果反饋給其他對象)。
責任并不涉及任何具體的實現方法。當我們說一個對象持有某一信息時,并非意味著在實現細節上它就直接存儲有關信息的數據。
?
責任與實現
?????????
當實現一個具體對象時,你將創建代表對象責任的抽象類和具體類
?????????
隱含在接口中的設計思路是:單一角色可以由多個不同類型的對象實現,而不管它們的具體實現方式。
?????????
對象之間可能從事相似工作,可實現方法不同,你需要考慮如下
3
中情況的區別:承擔共同責任,且實現也必須相同;承擔共同責任,但需要不同的實現;看似承擔了共同的責任,實際上卻不是。
責任來自哪里
P93
我們給對象分配責任的策略很簡單:覆蓋到所有重要的方面。尋找需要執行的動作以及需要維護和生成的信息。
?
我們可以考慮如下幾種獲得責任的方法:
1)???????
確認系統責任聲明或將其隱含在用例中。用例
說明了軟件系統的行為以及用戶如何與其交互,對軟件系統的功能進行了粗線條的描述,卻并不說明所有這些功能是如何實現的。責任是對象所知、所作和所能判斷的一般聲明。具體的用例轉責任的步驟如下:
l????????
識別系統所做的事和所掌控的信息
l????????
將這些事和信息抽象成責任
l????????
需要的話,將責任劃分成更小的部分,并分配給合適的對象。
2)???????
通過添加低級別的責任來彌補用例和系統描述之間的溝壑
3)???????
從設計主題和設計提綱中提煉出額外的系統行為
4)???????
遵循“
what if
…
then
…
and how
”的推理鏈
5)???????
識別匹配對象角色的構造型責任
6)???????
搜尋每個候選對象的更深層本質特征
7)???????
識別出支持對象之間的關聯和從屬依賴的責任
8)???????
識別出與對象的主要動作相關聯的責任
9)???????
識別出對象是和特定軟件環境所具備的技術責任
P93
識別責任的方法主要歸為以下三類:從客觀描述中發現它們、獨立的創造它們和從顯示的業務建模中添加細節來完善他們。
?
舉例:
MVC
???
摘自
Pattern-Oriented Software Architecture(John Wiey,1996)
對于
MVC
角色的各項責任的描述。
Model
l?
代表一個與應用相關的對象,可以被修改和顯示
l?
獨立于
View
對象和
Controller
對象
l?
發生狀態改變后會通知其他相關對象
View
l????????
創建并且初始化與它關聯的
Controller
l????????
向用戶展現信息
l????????
執行更新流程
l????????
從
Model
對象中獲得顯示信息
Controller
l????????
接受用戶輸入,并將輸入看成對某種事件的觸發
l????????
把事件轉換成對
Model
的服務請求或者對
View
的顯示請求
l????????
如果需要,執行更新流程
2007
年
3
月
23
日星期五
怎樣分配責任
l????????
從一般化的陳述責任開始
要泛化地、一般化地去陳述責任。不要把責任表達成個別的屬性或操作。
l????????
確定描述的正確層次
P108
你對責任的陳述,應該不要多少知識背景就能理解。
l????????
使用強烈描述
???
責任描述越強烈,設計就越精準。
l????????
做一個機會主義者
l????????
決定對象將如何分割或共同承擔一個龐大、復雜的責任
對象履行責任時有
3
種選擇,你可以任選其一:
?????????
親自完成所有的工作
?????????
請求其他對象幫忙完成部分工作(和其他對象協作)——此時,對象之間應該是組合關系
?????????
將整個服務請求委托給另外的幫助對象。
l????????
確保對象不會超負荷工作
l????????
將行為與信息關聯
即
GRASP
模式中的“信息專家”模式
l????????
分散系統的智能(
intelligence
)
記住,我們的目標不是為對象均勻的分配智能,而是讓它們承擔力所能及的責任。
l????????
將同一事物的信息集中于同一地方
如果有多個對象需要操作同一信息,那么存在以下
3
種可能的解決方案:
?????????
設計一個新對象作為信息的唯一存儲倉庫。此倉庫對象對于需要共享這一信息的對象都是可見的
?????????
某一對象或許已經承擔了與該信息相關的責任。在這種情況下,該對象可以承擔維護該信息的責任。其他對象需要信息時,可以向它發送請求。
?????????
可能的話,將需要共享信息的對象融合成一個對象。(我覺得這或許意味著已開始的設計就有問題)這意味著將請求信息的行為封裝到一個對象中,消除了對象差異。因為,由于過度設計,我們將責任劃分的太細,分配給了太多對象。因此,把這些對象融合成更單一、責任更強的對象才是更好的設計選擇。
?
下面作者給的這個例子相當經典,我以前在設計對象時,就存在這樣的誤區,而且大多數我身邊的初級建模者都會考慮單據上有什么,設計的對象就要包含什么屬性。
???
僅僅因為“顧客名”會出現在發票單上,就認為“發票單”對象應該持有顧客名信息這是不正確的。當需要打印的時候,它可以通過向協作對象發送請求來去的顧客名。
l????????
保持對象的責任連貫一致
對象的所有責任應該相互關聯,并且符合對象所扮演的角色。對象作為整體,應該是責任的總和。各個責任之間應有一種相互補充的關系。對象所知、所做的一切應該都服務于它的使命以及設計模型。
l????????
將對象的責任約束到單一領域中
l????????
避免承擔非本質責任
l????????
不要重復責任
除非系統有明確的冗余要求,否則沒有必要讓多個對象負擔著相同而重復的責任。