今天,本站帶領大家來熟悉一下UML中的組件圖。
組件圖(Component Diagram)又稱構件圖,是UML中描述一個系統中的物理方面的圖形,它是用來描述構成系統的各個組件、組件提供的接口與需求的接口、端口以及它們之間關系的圖。
這種圖在基于組件開發的系統建模中很重要。
組件圖可以幫助用戶理解系統的結構。
組件圖中主要包括組件、接口及其它們之間的關系三種元素。
組件(Component)是定義了良好接口的、可重用的、可替代的物理實現單元,它一般表示實際存在的、物理的物件。
程序源代碼、可執行文件、子系統、一個腳本、動態鏈接庫(DLL)、ActiveX控件都可以成為系統中的組件。
組件隱藏了內部實現的細節,僅通過接口提供服務。
我們可以把組件理解為一個黑盒子,這個黑盒子使用接口來公開其公共可見的屬性及操作,這一點與類非常相似。
在UML1.x版本中,一個標準的組件使用如下的圖形來表示。
而在UML2.x中一般使用如下的圖形來表示一個組件。
也可以使用類似類的矩形框加上構造型<<component>>來表示組件,如下圖所示:
組件中的接口主要分為兩類:提供接口(Provided Interface)和需求接口(Required Interface)。
提供接口又稱導出接口,是組件提供的服務的集合。
提供接口是由組件本身直接實現的接口、或者是由實現組件的類之一實現的接口,或者是由組件的公共端口提供的接口。
提供接口可以使用接口與組件之間的實現關系來表示。
提供接口可以在組件圖標的邊框上使用類似棒棒糖式(lollipop)的圖標來表示。如下圖所示:
這個圖表示WeatherServices組件提供或實現了WeatherForecast接口。
它可以認為是下圖的簡化表示方法:
需求接口又稱導入接口,是組件請求其它組件相應服務時遵循的接口。
需求接口通過依賴關系來表示,需求接口可以使用插座(Socket)的圖標連接到組件邊框上來表示,如下圖所示:
上面這個圖表示UserServices組件需要(依賴)IOrderServices接口。
它可以認為是下圖的簡化表示方法:
作為一種可選方式,可以把組件的接口或組件的操作和屬性列在組件圖標下邊的隔室里。
上面這個圖表示,UserServices接口提供的接口有IUserServices,需求的接口有IOrderServices。
端口用于描述組件或類與它的環境、與其它類、與其它組件或內部部件的交互點。這個交互點一般是組件或類的一個屬性,默認情況下,端口具有公共可見性。
端口使用類或組件邊框上的一個小矩形來表示,如下圖所示:
上圖表示BorrowServices組件有一個borrowPort端口。
接口通過端口來提供服務或獲得服務,下圖表示了這種情況:
組件圖中的關系主要包括兩種:依賴關系和實現關系。
組件圖中的依賴關系與類圖中相同,都是“供應者-客戶”關系(supplier-client),使用虛線箭頭由客戶(client)組件指向供應者(supplier)組件。
下圖表示組件“borrowBook”依賴于組件“Book”,其中,“borrowBook”是客戶組件,Book是供應者組件。
下圖也表示了兩個組件之間的依賴關系,它表示了borrowBook組件的一個需求接口依賴于Book組件的一個提供接口:
一般這種依賴關系都是從插座接口引出指向棒棒糖接口。
上圖也可以簡化成下面的形式:
上面這個圖表示了borrowBook使用某個需求接口與Book組件的提供接口產生依賴關系。
這種圖在UML2.x中被定義為連接。
組件之間的實現關系表示一個組件實現了另外一個組件。這與類和接口之間的實現關系相同。
下面第一個圖表示組件borrowBook實現了組件IBorrowBook。
如果IBorrowBook組件僅包含一個接口的話,也可以使用第二個圖來表示(見上面關于組件提供接口的說明)。
組件實現了一個接口意味著組件支持接口中的所有操作。
Scott W.Ambler在其著作《The Object Primer:Agile Model-Driven Development with UML 2.0》第三版中給出了關于組件建模技術的一些方法和技巧:
在實際組件建模中可以采用自頂向下的方法,也可以使用自底向上的方法。
使用自頂向下的建模方法可以使設計人員能夠更清晰的了解軟件的未來架構,但這種方法容易導致系統的過度架構化,從而導致系統的過度建模,易使設計人員過度關注細節,而忽略了客戶的真正需求。
使用自底而上的方法可以在類建模的基礎上把已設計的類進行組件化,把系統中可重用的部分分離出來,或者將應用程序進行拆分,以便把任務輕松地分配給相應的團隊。
在組件建模中可以使用如下步驟或原則進行建模:
(1)保持組件的內聚性
一個組件應保持其功能單一性或功能相關性。如,一個組件僅包含某類用戶的用戶界面、或者僅包含大規模領域概念的業務類,或者僅包含公共基礎概念的技術類。
(2)將用戶界面類分配給應用程序組件
用戶界面類,如頁面、報告以及實現相關邏輯的類,應該放在帶有“application”構造型的組件中。如Java中JSP頁面、servlet和Swing類等。
(3)把技術類分配到基礎架構組件中
實現系統級服務的類,如安全、持久性或中間件,應該分配到帶有“infrastructure”構造型的組件中。
(4)定義類的契約
類契約是指能夠直接響應其它對象發送的消息的方法(操作)。
如在Books類中很可能包括getBookInfo()這樣的方法,這樣的方法能夠響應來自其它組件中對象發送的消息。
為了很好的識別組件,你可以忽略所有非類契約的操作,原因是這些操作對促進分布在不同組件中的對象之間進行通信不會提供太大幫助。
(5)把一個具有層次結構的所有類(如類的繼承或聚合層次結構)分配到相同組件中。
(6)識別領域組件
若干類相互協作以完成特定的任務,這些類滿足內聚要求,從而成為一個領域組件。其它類或組件能夠通過向該領域組件發送消息以請求獲得信息或執行操作。領域組件對外顯示出其簡單性,但其內部通常很復雜。領域組件設計的目標是減少網絡通信,而使大多數信息流發生在其內部。
(7)確定業務類的協作類型
服務器類是接收消息但不發送消息的類;客戶類是發送消息但不接收消息的類;客戶/服務類是兼有發送消息和接收消息的類;在確定好每個類的分布類型后,就可以開始確定潛在的領域組件了。
(8)把服務器類歸為一個組件中
純服務器類屬于領域組件,他們是應用程序中消息流的“最后一站”。
(9)將僅為某客戶端類服務的組件合并到其客戶組件中
如果一個領域組件僅為某一個組件提供服務,那么可以把這兩個組件合并為一個組件。
(10)單純的客戶端類不應歸到領域組件中
客戶端類只生成消息而不接收消息,不應屬于領域組件。領域組件的目的是響應消息。客戶端類很可能屬于應用程序組件。
(11)高度耦合的類應歸為一個組件中
兩個頻繁協作的類應位于相同的領域組件,以減少兩個類之間的網絡流。即,高度耦合的類應放在一起。
(12)遵循最小化組件間的消息流原則
在確定一個客戶類/服務類屬于哪個組件時,要充分考慮流入和流出類的信息流。組件內的通信通常是在內存中對象之間簡單的消息發送。組件間的通信往往需要消息的轉換、傳輸等額外的支出。
(13)定義組件的契約
每個組件應向客戶提供服務,這樣的服務即為組件的契約。
Rational Rose支持1.x的組件圖繪制方法,其能表示組件與接口之間的實現關系以及組件之間的依賴關系,但不能繪制“Socket”插座式的需求接口形式。用戶在實際中可以通過接口之間的依賴來表達。
在Rose中,在組件視圖(Component View)中創建組件圖,可以在Rose中左側的瀏覽器中的“Component View”上右擊,然后選擇“New”->“Component Diagram”。
使用組件圖創建工具欄中的“組件”可以創建一個組件。
組件圖中的工具箱如下圖所示:
選“組件”工具后,在繪圖區點擊一下即可以完成一個組件的創建。
(1)用戶在創建組件時,可以直接修改組件的名稱;
(2)在左側瀏覽器中,選中要修改名稱的組件,然后右擊后選擇“Rename”,最后,輸入新的名稱即可,具體如下圖所示:
(3)在繪圖區中,在對應的組件上右擊后,在彈出的快捷菜單中選擇“Open Standard Specification...”。
這個操作會打開如下圖所示的對話框:
在這個對話框的“Name”中可以輸入新的組件名稱。
在Rose中,要徹底刪除一個組件,可以通過以下幾種方式:
(1)在繪圖區中,右擊要刪除的組件,在彈出的快捷菜單中選擇“Edit”->“Delete from Model”菜單項;
(2)選中要刪除的組件,按下“Ctrl+D”組合鍵,則可以快速刪除組件;
(3)選中要刪除的組件,選擇菜單欄中的“Edit”->“Delete from Model”菜單項;
(4)在左側瀏覽器中,在要刪除的組件上右擊后,在彈出的菜單中選擇“Delete”。
以上的四種操作方法,將會把組件在所有模型中徹底刪除。
如果其它模型中使用了該組件,且只是把組件從當前模型中的話,用戶可以選中組件后,直接按下鍵盤中的“Delete”鍵即可,或者右擊要刪除的組件后,在快捷菜單中選擇“Edit”->“Delete”也可以實現該操作。
在Rose中,可以為組件指定其要實現的接口(提供接口——Provided Interface),具體操作方法如下:
(1)右擊要設置的組件,在彈出的快捷菜單中選擇“Open Standard Specification...”;
(2)在彈出的對話框中選擇“Realizes”選項卡,該選項卡中列出了模型中所有的類和接口,具體情形如下圖所示:
(3)在要實現的接口上右擊后,選擇“Assign”(分配)菜單項。
操作情形如下圖所示:
分配完接口后的組件及操作對話框后的情形如下圖所示:
我們可以看到,組件上多了兩個接口(提供接口),同時在“Realizes”列表中,以分配到該組件的接口上將出現紅色的“√”符號。
為組件指定實現的接口后的樣子如下圖所示:
它表示IBook和IReader接口在組件BorrowBooks中實現的,也表示BorrowBooks提供了IBook和IReader兩個接口(提供接口)。
如果用戶想把一個接口從組件中移除,用戶可以在列表中的組件上右擊后,在彈出的菜單中選擇“Remove Assignment”菜單項。
實際上,以上操作相當于定義了組件和接口之間的實現關系。
用戶也可以使用同樣的方法,把組件中包含的類分配到某個組件中。
(4)添加依賴關系
組件圖中的依賴關系需要借助工具欄中的“依賴”工具來實現。
具體操作辦法如下:
①用戶點擊“依賴”工具;
②在依賴元素上點擊后,一直按住鼠標左鍵,拖動鼠標到被依賴元素上松開鼠標左鍵,則完成了元素之間的依賴關系。
如下圖顯示了組件“Fine”和接口“IFineRecords”之間的依賴關系。
它相當于組件的需求接口(Required Interface)。
Visio中雖然提供了一些繪制UML圖的模板,但沒有提供專門繪制組件圖的模板。但用戶可以在Pavel Hruby博士的網站上下載專門用于繪制UML圖的Visio模具包。
這個Visio模具包叫“Visio Stencil for UML”。
該模板可以支持UML2.5中的各種圖形,包括用例圖、類圖、時序圖、包圖、狀態機圖、組件圖等。
你可以在微信搜索“優雅的代碼”訂閱號,關注后,消息中回復“visio uml”關鍵字來獲取該模板的下載地址。
下載后,把這個模具包解壓縮到你的電腦某個磁盤中的某個目錄中以備使用。
Visio Stencil for UML針對不同的Visio版本有不同的模具。正常情況下高版本的Visio可以支持低版本的Visio Stencil for UML。
(1)打開Visio,新建繪圖;
(2)選擇“更多形狀”,然后選擇“打開模具”;
(3)選擇你解壓縮后的Visio Stencil for UML模具。
這樣,就可以把下載的模具加載到繪圖區中來了。
你也可以把下載解壓縮的文件放到Visio默認的模具路徑中,具體操作方法為:
在“文件”菜單中選擇“選項”,然后在左側選擇“保存”項,在右側列出的內容中找到“默認個人模板位置”,這里是模板保存的路徑,你可以把解壓縮后的Visio Stencil for UML文件復制到這個文件夾中。
或者你在這里直接輸入Visio Stencil for UML所在的路徑。
下圖顯示了這個工具中提供的繪制UML圖的全部圖形符號。
同時,在下載的工具中也提供了一些UML其它的構造型符號供設計時使用。
(1)添加一個組件
在左側形狀中,選擇“Component”(組件),然后把它拖曳到繪圖區中來。
(2)輸入名稱
雙擊組件符號,輸入或修改組件的名稱。
(3)調整組件顯示大小
如果需要調整組件的大小,可以選中組件,在其周圍會出現若干個白色的小方塊,如下圖所示:
鼠標到上面會變成雙向箭頭的形狀,然后按住鼠標左鍵,通過拖拽來改變圖形的顯示大小。
(4)修改字體
選中組件后,在“開始”功能區的“字體”分組中可以修改字體、顏色以及字體的大小、是否加粗、是否有下劃線等設置,如下圖所示:
在左側形狀中選擇“Interface,Socket”圖形,如下圖所示的圖形:
然后把它拖曳到繪圖區中的組件附近,這時,相應的組件周圍會出現若干貼附點,如下圖所示:
選擇一個貼附點,然后松開鼠標后,其會變成如下的形式:
用戶可以選中接口,通過按住圈中(接口)的黃色小方框來拉長接口的線。
默認是提供接口(Provided Interface)的形狀,如果想要添加需求接口(Required Interface),則只需在添加的接口上右擊,然后選擇“Socket”即可,如下圖所示:
則原來的提供接口的形狀就變成了需求接口的形狀,如下圖所示:
在這個工具中可以通過在繪圖中添加“Straight Relationship”為組件圖中添加依賴關系。
然后將其微端連接到依賴元素的貼附點上,其頭端連接到被依賴元素的貼附點上。
默認添加的“Straight Relationship”為一條直線,情形如下圖所示:
用戶可以通過右擊這個直線,然后在菜單列表中選擇“Dependency”,即完成依賴關系的繪制。
下圖是修改完聯系類型的情形:
下面是圖書館借閱系統中的組件圖,這個組件圖即是使用上面介紹的Visio Stencil for UML工具創建而成的。
下圖是在Rose中實現的例子:
新聞熱點
疑難解答