在UML2十三款圖中,使用案例圖、類別圖和循序圖的重要性排名前三大。簡單來說,我們用使用案例圖來呈現資訊系統提供給外界使用者的服務或功能,並且使用類別圖來設計資訊系統內部的靜態結構,同時使用循序圖來表達資訊系統內部一群物件之間的互動行為。所以,我們只要透過這三款圖,便可以花費最低成本來呈現資訊系統的對外功能、靜態結構和動態行為。
前面陸續介紹了使用案例圖和類別圖的風格指南,本期談完類別圖最後一個單元,就開始進入循序圖的指南介紹。
類別圖的聚合與組合關係
結合(association)是一種平等關係,但是有時我們可能會需要表達,整體-部分(whole-part)這種一大一小或一重一輕的不平等關係。
所以,UML以結合關係為基礎,延伸出「聚合關係」(aggregation association)與「組合關係」(composition aggregation),來表達兩種整體-部分的概念。
請看圖1,如果我們想要傳達團隊物件是群體,而另一成員物件是它的聚集成員,這樣的整體-部分概念時,就可以採用聚合關係。
或者,我們想要傳達剪刀物件是整體,而另一刀柄物件及刀片物件是它的內部組件,這樣的整體-部分狀況時,很適合採用組合關係,如圖2所示。
簡單來說,聚合關係跟結合關係的最主要差異,就在於整體-部份特質,除此之外,兩者就沒有什麼差異了。不過,組合關係就大不同了,它除了同樣具有整體-部分的特色外,跟聚合關係最大的不同之處在於,組合關係中的整體直接掌握部分的生滅,聚合關係中的整體並不具有生滅部分的權力。所以,一旦組合關係中的整體物件不復存在時,組成它的部份物件也不能單獨存在,必須同時消滅。
接下來從編號140到145這六條指南,用於聚合與組合關係,同時也是跟類別圖有關的最後一部份指南,看完了這幾條指南後,我們就終於可以脫離繁瑣的類別圖,進入另一個跟循序圖有關的指南了!
指南140 把語句規則應用在聚合關係上(Apply the Sentence Rule for Aggregation)
聚合關係的語句規則是指「部分是整體的一部分(the part IS PART OF the whole)」,例如圖3,我們會說「部門是公司的一部分」,所以它們之間就有聚合關係。
指南141 對「整體」與「部分」皆感興趣 (Be Interested in Both the Whole and the Part)
只有對整體與部分皆感興趣的情況下,才需要使用聚合或組合關係。比方說,我們關注「檯燈」,但不在乎「燈管」,即便在真實世界中,燈管是檯燈的重要組成元素,但在我們的設計圖中,還是只會出現檯燈,不會出現燈管。
指南142 把整體放置於部分的左邊(Place the Whole to the Left of the Part)
一般的習慣是將整體放置於部分的左邊,如圖4所示。
指南143 在表達實體物品的聚合現象時,可以使用組合關係(Apply Composition to Aggregates of Physical Items)
指南144 當部分跟整體共享自己永續的生命週期時,可以使用組合關係(Apply Composition When the Parts Share Their Persistence Life Cycle with the Whole)
指南 145 別擔心菱形(Don’t Worry About the Diamonds)
最後,編號143到144這兩條指南,很明確地建議,如果是實體物品的聚合時,考慮採用組合關係或許會比較恰當。這也是因為通常實體物品的部分,會跟它的整體共享生命週期,講白了就是,整體可以決定部分的生滅。
由於,聚合和組合關係之間僅有細微的差異,所以許多人搞不清楚如何區辨兩者,特別是初學者。所以,原著作者乾脆列了第145條指南建議讀者,如果搞不清楚聚合和組合之間的差異,那不如就別理它們了,把它們拋在一旁,別用就是了。
其實,UML有許多罕見又難懂的細微概念,說真的,如果真的搞不清楚,就別用了吧,因為如果需要花很多時間才能搞懂這些概念的話,那未免也太花學習成本了,同時也會耗掉太高的溝通成本吧!
循序圖
緊接著,我們會依序看到跟循序圖相關編號158到182這二十五條指南,共分為四個單元:一般、存活線(lifeline)、訊息(message)和回傳值。
一般
指南158 由左向右依序放置訊息(Strive for Left-to-Right Ordering of Messages)
在循序圖面上,訊息的發生順序通常從上到下、由左至右依序發生,正因如此,這款圖才會叫做「循序圖」或「順序圖」啊!
雖然,從圖面上我們就可以判斷訊息發送的先後順序,不過大部分的UML工具都還是會提供標示序號的功能,方便我們一眼就知道訊息發送的順序,像圖5就是StarUML的設定機制。
指南159 依層級放置物件存活線(Layer Object Lifelines)
如果在循序圖中有採用層級(layer)的設計概念的話,可以依層級擺放物件存活線。
比方說,經典的三層式架構設計概念,將系統內部物件分為三個層級,分別為:負責使用介面的介面層(UI layer)、管理企業邏輯的企業層(business layer)、維護資料的永續層(persistence layer)。
所以在擺放物件存活線時,就可以依照介面層、企業層、永續層順序擺放,如圖6所示。
指南160 如果需要的話,參與者與類別可以同名(Give an Actor the Same Name as a Class, If Necessary)
由於,參與者代表系統外部、真實世界裡頭的物件,而其餘物件則代表系統內部的軟體物件,所以即便兩者同名,也代表不同的概念,如圖7所示。
指南161 包含邏輯敘述(Include a Prose Description of the Logic)
在循序圖面上,可以於最左邊的地方,放置文字敘述,用來描述整張圖的邏輯控制,便於理解與溝通,如下圖8所示。
指南162 將主動性的系統參與者放置在循序圖的最左側(Place Proactive System Actors on the Leftmost Side of Your Diagram)
指南 163 將被動性的系統參與者放置在循序圖的最右側(Place Reactive System Actors on the Rightmost Side of Your Diagram)
通常,我們會將具有主動特質的主要參與者放置於循序圖的最左邊,同時將具有被動特質的次要參與者放置於循序圖的最右邊。
請先看到圖9的使用案例圖,一共有兩個參與者會參與「刷卡結帳」的使用案例,所以對應到圖10的刷卡結帳循序圖中,主要參與者—會員將置於圖面的最左側,而次要參與者—信用卡系統則置於圖面的最右側。
指南164 避免繪製物件的消滅狀況(Avoid Modeling Object Destruction)
指南165 避免繪製活動期的長條框(Avoid Activation Boxes)
消滅訊息與活動期是兩個完全不同的概念,不過我們將它們放在一起來說,統一參照圖11的圖示。消滅訊息是一個大叉叉的圖示,出現在存活線的底端,代表該物件被消滅了、不再存活了。而活動期的圖示是長條矩形,放置於存活線上,代表該物件在接收到訊息之後,會有一段執行時間。
許多UML工具都有支援隱藏活動期圖示的功能,像StarUML就有這樣的功能,如圖12所示。
原著作者不建議使用消滅訊息和活動期的主要原因都跟記憶體管理有關,像是消滅訊息意味著該物件的記憶體將被回收。
關於消滅訊息,到底意味著該物件的記憶體將被回收,還是只是單純意味著該物件將被消滅、不再存活了,一直都有這兩派不同的解釋,端看你採用哪一種說詞。
不過,如果根據UML規格書的內容,倒是沒有明確指出消滅訊息跟記憶體配置有關,所以我個人是比較支持第二種說法,讓消滅訊息單純意味著物件將被消滅、不復存在。
存活線
在循序圖上,頂頭連接物件矩形的直立虛線,就是代表物件活著的存活線,它是循序圖中極為重要的元素之一。接下來,編號166到169,一共四條指南都跟存活線有關,繼續往下看吧!
指南166 在訊息中有參考使用到某物件時,才為該物件命名(Name Objects Only When You Reference Them in Messages)
指南167 當存在數個相同型別的物件時,才為這些物件命名(Name Objects When Several of the Same Type Exist)
通常,我們不會為循序圖中的物件命名,因為物件有成千上百個,一一命名太過繁瑣,也沒有必要。不過,如指南166和167所言,通常在上述兩種狀況的時候,我們才會為了辨識物件,而為物件命名,如圖13所示。
指南168 在存活線上,一致性地使用文字模版(Apply Textual Stereotypes to Lifelines Consistently)
既然,模版(stereotype)可以讓我們添加額外的資訊,我們當然可以在存活線上使用模版。比方說,在圖14的範例中,我們可以透過《UI》、《Business》和《Persistence》將三層式的設計概念放到存活線上。
指南169 聚焦於關鍵性的互動上(Focus on Critical Interactions)
通常,我們會希望循序圖可以聚焦企業邏輯上頭,也就是這條指南所建議的關鍵性互動,而不是把所有瑣碎的細節照單全收地表達在循序圖中。這樣一來,不僅可以提高建模的產能,也可以提高模式的可讀性。
訊息
到目前為止,循序圖的指南都很容易理解,此處從編號170到176這七條跟訊息有關的指南,也同樣好懂,可以放輕鬆繼續往下看!
指南 170 將訊息名稱放置於訊息箭頭旁(Justify Message Names Beside the Arrowhead)
因為訊息的接收物件需要實作該訊息,所以,訊息名稱當然是擺在靠近接受物件的箭頭端處,比較合理,如圖15所示。
指南171 直接建立物件(Create Objects Directly)
還記得前面提到圖示為大叉叉的消滅訊息嗎?物件有生有滅,所以相對於消滅訊息,UML也定義了一個「誕生訊息」(create message)。顧名思義,誕生訊息用來標示出物件的誕生,在圖16中射向矩形的帶開放性箭頭虛線,就是誕生訊息,意味著物件a發出一個誕生訊息,因此誕生了物件b。
原著作者的建議是說,如果遇到誕生訊息時,請採用圖16的圖示直接表達誕生訊息,這樣可以讓觀看者一目暸然,一眼就知道這是個誕生訊息,避免使用圖17的《create》間接表示法。
指南 172 以操作簽名做為軟體訊息的名稱(Apply Operation Signatures for Software Messages)
指南173 涉及人類或組織參與者的訊息,以一般的散文體命名(Apply Prose to Messages Involving Human and Organization Actors)
如果,該訊息涉及到人類參與者或組織參與者,無論是這兩類參與者扮演發出端或接收端物件,都以一般日常對話的方式簡短命名訊息。但是,倘若該訊息發生在兩軟體物件之間的話,訊息名稱可以和操作簽名相同,而且採用程式語言的表達方式。指南174 列出參數的名稱,優於列出參數的型別(Prefer Names over Types for Parameters)
指南175 標示出型別,代替參數名稱(Indicate Types as Parameter Placeholders)
只列出參數的型別,而沒有列出參數的名稱的話,經常無法知道這是個什麼樣的參數,所以列出參數名稱優先於型別。不過,也並非總是如此,有些型別本身就含有詳細的資訊時,採用型別反而比參數名稱更適當。
原著作者有提到兩個很不錯的例子,引用說明如下:
●addDeposit(amount, target, transactionID)—如果採用型別表示參數的話,如addDeposit(Currency, Account, int),便難以判斷這三個參數是什麼,要是改用addDeposit(amount, target, transactionID)的參數名稱表達方式的話,就可以很清楚知道這三個參數的意義,採用指南174的建議。
●start(UserID)—UserID雖然是個型別,可是從型別名稱本身就已經含有詳細的資訊了,所以直接使用型別,代替參數名稱,採用指南175的建議。
不過,要澄清的是,在UML的表示法上,上述兩個的原著範例有些錯誤,正確的格式如圖18所示。切記,如果只要表達型別而不表達參數名稱的話,不得省略型別前方的冒號。
此外,多數的UML工具都有提供數種不同的顯示方式,像是圖19的StarUML就提供了四種顯示方式。
指南176 遇到呼叫使用案例時,可以使用《include》字標(Apply the 《include》 Stereotype for Use Case Invocations)
如果在循序圖中,要秀出呼叫某個使用案例的話,可以在訊息處加上《include》字標。比方說,遇到像圖20的使用案例圖,在查詢餘額的循序圖中,就可以呼叫檢驗晶片金融卡使用案例,如圖21所示。
原著作者提出了這個很有創意的表達方法,不過大部分的UML工具都不支持將使用案例的橢圓放置於循序圖中,也就是說,循序圖中是不能呼叫使用案例的。
最主要的因素在於,循序圖與使用案例是兩個不同的觀點,循序圖用來表達系統內部物件互動的情況,而使用案例則代表系統外部使用者參與系統流程的情況。
再者,我們還可以看到UML規格書中的母模設計,如圖22所示。在循序圖中,存活線上方的矩形稱之為「可接元素」(connectable element)。我們可以看到在圖22的繼承架構中,雖然「使用案例」(use case)跟可接元素有相同的祖先,可是使用案例仍舊無法被當作成可接元素。我想,或許這也是多數UML工具無法支援圖21表示法的原因之一。
回傳值
這裡的回傳值是指訊息所附帶的回傳值,有關的指南一共有六條,編號由177到182。
指南177 不要在圖中表達明顯的回傳值(Do Not Model Obvious Return Values)
指南178 需要參考到回傳值時,才在圖中表達回傳值(Model a Return Value Only When You Need to Refer to It Elsewhere in a Diagram)
圖並不是要百分之百表達真實情況,套上80/20法則來說,圖所呈現的資料量只有百分之二十,但是我們用圖來強調百分之八十的關鍵性資訊。所以了,明顯的回傳值不需要表達出來就可以聯想到,這就不要表達了,除非是遇到其他訊息需要參考到該回傳值,這就另當別論了。
什麼樣的回傳值是明顯的呢?舉例來說,如果有一個名為「取得總額」(getTotal)的訊息,就可以不用特別表達它的回傳值,因為可以聯想到取得總額就是會回傳總額(total)啊!
指南179 將回傳值放置於回覆訊息箭頭旁(Justify Return Values Beside the Arrowheads)
指南180 把回傳值視為方法的一部分(Model Return Values as Part of a Method Invocation)
指南181 標示出型別,代替回傳值(Indicate Types as Return-Value Placeholders)
指南182 簡單的回傳值,可以直接標示出實際數值(Indicate the Actual Value for Simple Return Values)
回覆訊息(reply message)的圖示是帶開放性箭頭的虛線,由負責執行訊息的接收物件反向指回發送物件,如圖23所示。
再者,我們也可以省略回覆訊息,以便節省版面空間,將回傳值標示於訊息處,如下列範例所述:
● total=calcTotal()—把回傳值視為方法的一部分,指派回傳值給total參數。採用180號指南的建議。
● calcTotal():Double—標示回傳值的型別Double。採用181號指南的建議。
● total=calcTotal():5000—指派回傳值給total參數,並且直接標示出真實數值為5000。採用182號指南的建議。
介紹完循序圖,等於介紹完書中最主要的三種UML圖,最後要介紹的部分,原本收錄在原著第三章中,屬於共用圖示的指南,編號從27到57,一共三十一條指南,分為四個次小節:註解、模版、框架(frame)和介面(interface)。
下一期,將從註解的相關UML指南開始談起。
Amazon軟體開發類暢銷書排行榜 |
Beginning iPhone Development: Exploring the iPhone SDK 出版時間:2008.11.14 出版社:Apress |
Learn Objective–C on the Mac (Learn Series) 出版時間:2009.1.2 出版社:Apress |
Code Complete: A Practical Handbook of Software Construction 出版時間:2004.7.7 出版社:Microsoft Press |
Pro C# 2008 and the .NET 3.5 Platform第四版(Windows.Net) 出版時間:2007.11.12 出版社:Apress |
JavaScript: The Good Parts 出版時間:2008.5.15 出版社:O'Reilly |
Using Drupal 出版時間:2008.12.16 出版社:O'Reilly |
MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework Application Development Foundation第二版 出版時間:2008.11.12 出版社:Microsoft Press |
作者簡介:
邱郁惠
研究OOAD、UML、MDA十餘年,經歷過顧問、專案、教學及寫作工作。離職後創辦UML Blog推廣UML,組織《UML互助會》社群定期舉辦軟體技術講座,出版多本UML專業書籍與電子書。目前擁有OCUP/UML三級認證、PMP認證。
熱門新聞
2025-01-26
2025-01-25
2025-01-26
2025-01-27
2025-01-26
2025-01-27