?
(零雨其蒙原創(chuàng) 轉載請注明)
2007
年
3
月
4
日星期日
?
第
17
章
GRASP
:基于職責設計對象
P197
最關鍵的軟件開發(fā)工具是受過良好設計原則訓練的思維,
而不是
UML
或任何其他技術。
?
?
P197
總架構師利用
UML
包圖
提出大型邏輯架構的構思。
?
開始設計需要輸入的制品
(這些制品都是分析階段的產物)
用例文本
定義最終必須得到軟件對象的支持(對象必須能夠實現實例)的可視行為。在
UP
中,這種
OO
設計也被順理成章地稱為用例實現。
|
補充規(guī)格說明
定義了非功能性的目標,例如國際化,我們的對象必須滿足這些目標。
|
系統(tǒng)順序圖(
SSD
)
確定系統(tǒng)操作信息,它是合作對象交互圖中的開始消息。
|
詞匯表
明確來自
UI
層的參數或數據、傳遞到數據庫的數據細節(jié),以及詳細的特定項邏輯或驗證需求,如合法的格式和對產品
UPC
(童用產品代碼)的有效性驗證。
|
操作契約
用來補充用例文本,以明確在系統(tǒng)操作中軟件對象必須完成什么任務。后置條件定義了系統(tǒng)操作的詳細結果
|
領域模型
描述了軟件架構的領域層軟件領域對象的名稱和屬性
|
?
通過用例文本描述需求,
用例就是需求,主要是說明系統(tǒng)如何工作的功能性或行為性需求。(
P48
)而
SSD
,操作契約和詞匯表是對用例中的功能或行為需求的細化和補充,其中操作契約是對
SSD
中的操作的詳細描述;補充規(guī)格說明則是對整個需求分析過程中用例未能描述的非功能目標的補充。
SSD
會幫助
DCD
過程交互圖的繪制,領域模型則會啟發(fā)領域層軟件領域對象的名稱和屬性的設計。
?
RDD
P198? OO
設計建模的總的來說,基于職責驅動設計(
RDD
)所代表的內在含義是考慮怎樣給協(xié)作中對象分配職責。
?
P200
RDD
是一種隱喻
RDD
是思考
OO
軟件設計的一般性隱喻。把軟件對象想象成具有某種職責的人,他要與其他人協(xié)作以完成工作。
RDD
使我們把
OO
設計看作是
有職責對象進行協(xié)作
的共同體。
|
?
?
職責和職責驅動設計
思考軟件對象設計以及大型構件的流行方式是,考慮其職責、角色和協(xié)作。這是被稱為職責驅動設計
[WM02]
大型方法的一部分。
?
軟件對象的職責,即對其所作所為的抽象。
UML
把職責定義為“類元的契約和義務”
[OMG03b]
。就對象的角色而言,職責與對象的義務和行為相關。職責分為以下兩種類型:
行為
和
認知
。
?
對象的行為職責包括:
l????????
自身執(zhí)行一些行為,如創(chuàng)建對象或計算。
l????????
初始化其他對象中的動作
l????????
控制和協(xié)調其他對象中的活動
對象的認知職責包括:
l????????
對私有封裝數據的認知
l????????
對相關對象的認知
l????????
對其能夠導出或計算的事物的認識
在對象設計中,職責分配給對象類。
例如,我可以聲明“
Sale
負責創(chuàng)建
SalesLineItems
”(行為職責
1
),或“
Sale
負責認知其總額”(認知職責
3
)
?
職責與方法
職責與方法并非同一事物。
職責是一種抽象,而方法實現了職責。
職責借助于方法來實現,該方法既可以單獨動作,也可以與其他方法和對象協(xié)作。
?
GRASP
與
RDD
GRASP
(
General Responsibility Assignment Software Patterns
通用職責分配軟件模式)對一些基本的職責分配原則進行了命名和描述,因此掌握這些原則有助于支持
RDD
。
?
2007
年
3
月
5
日星期一
GRASP
模式
Creator
創(chuàng)建者
名稱:創(chuàng)建者
問題:誰創(chuàng)建了
A
?
解決方案:如果以下條件之一為真時(越多越好),將創(chuàng)建類
A
的實例的職責分配給類
B
(也就是
B
創(chuàng)建
A
,
B
應該和
A
有哪些關系或
B
應該具有哪些特征):
l????????
B
“包含”(比如
Board
(棋盤)“包含”
Square
(棋盤上的方格))或組成聚集(更準確的說法是組成聚合,也稱組合)了
A
l????????
B
記錄
A
l????????
B
緊密地使用
A
l????????
B
具有
A
的初始化數據
?
或許可以說,
B
依賴
A
,則
B
要創(chuàng)建
A
。
?
?
Information Expert
信息專家
名稱:信息專家
問題:給對象分配職責的基本原則是什么?
解決方案:把職責
分配
給具有完成該職責所需信息的那個類。
職責需要履行職責的信息,即關于其他對象的信息、對象自身的狀態(tài)、對象周圍的環(huán)境、對象能夠導出的信息,等等。
??
?
或許可以說,類的屬性(信息,認知)決定了類的方法(職責,行為),但從領域模型而來的設計模型(軟件中的類或接口或包)應該已經具備了這樣的特點。
?
Low Coupling
低耦合
名稱:低耦合
問題:如何減少因變化產生的影響?
解決方案:分配職責以使(不必要的)耦合保持在較低的水平。用該原則對可選方案進行評估。
?
或許可以說,低耦合是遵循信息專家原則的結果,也是設計對象的目標
?
P248
內部或自身較高的偶合度不是問題,反之與不穩(wěn)定
(可能該元素今天有明天就沒有了,它不是必要元素)的元素的耦合才是真正的問題所在。
?
Controller
控制器
在一些
OOA/D
方法中,
控制器
是對應用邏輯對象的命名,它接收請求并“控制”(協(xié)調)對請求的處理。
?
名稱:控制器
問題:在
UI
層之上,首先接收和協(xié)調(“控制”)系統(tǒng)操作的對象是什么?
解決方案:把職責分配給能代表下列選擇之一的對象(兩類控制器):
l????????
代表全部“系統(tǒng)”、“根對象”、運行軟件的設備或主要的子系統(tǒng)(這些是外觀控制器(
fa?ade controller
)的所有變體)。(這種控制器是領域對象)
l????????
代表發(fā)生系統(tǒng)操作的用例場景(用例或會話控制器(
session controller
,其例子或許是
EJB
的
Session Bean
))。
P221
如果你選擇用例控制器,那么對于每個用例,應用使用不同的控制器。這種控制器不是領域對象,它是支持系統(tǒng)的人工構造物(在
GRASP
模式的術語里是純虛構(
Pure Fabrication
))
?
我的理解是,從廣義上來講,控制器是連接
UI
和領域對象的紐帶,與所熟悉的應用(比如
MVC
中的
c
)所表現出來的用處一樣,對來自于
UI
層的消息進行接收和控制(分配(
委派
),調度(協(xié)調)等)。然而狹義一點說,按照
Larman
的說法,
MVC
中的
C
與
GRASP
中的
C
并非一物,前者是
UI
層的一部分,并且控制
UI
層的交互及頁面流。后者則是領域層的一部分,它控制或協(xié)調工作請求的處理,它根本不知道所用的
UI
技術(如
Web UI
,
Swing UI
,……)是什么。(
P222
)
然而根據系統(tǒng)操作的定義,和控制器模式的作用,我依然覺得
GRASP
控制器模式和
Struts
中的
Controller
是同一物,只不過
Larman
將其歸在了領域層,或者可以這樣理解,
MVC
中的控制器是
GRASP
控制器模式的特例,原因是其系統(tǒng)操作只包括處理
Web
頁面的輸入、點擊等事件。
?
P221
控制器模式的重要結果是,
UI
對象(例如,窗口或按鈕對象)和
UI
層不應具有實現系統(tǒng)事件的職責。換句話說,
系統(tǒng)操作
應當在對象的應用邏輯層或領域層進行處理,而不是在系統(tǒng)的
UI
層處理。
High Cohesion
高內聚
名稱:高內聚
問題:怎樣使對象保持有內聚、可理解和可管理,同時具有支持低耦合的附加作用?
解決方案:職責分配應保持高內聚,依此來評估備選方案。
?
我的理解是,內聚的含義是與其內部代碼和內部代碼的相關度有關的,高內聚表現為內部代碼相關度高。
?
?