1. 程式人生 > 其它 >UML 包圖 詳細介紹

UML 包圖 詳細介紹

6.1 包圖的概念

包是一種常規用途的組合機制。UML中的一個包直接對應於Java中的一個包,C#中的名稱空間。在Java中,一個包可能含有其他包、類或者同時含有這兩者。進行建模時,通常使用邏輯性的包,用於對模型進行組織;使用物理性的包,用於轉換成系統中的Java包。

C#名稱空間與java包的區別分析

本文例項分析了C#名稱空間與java包的區別。分享給大家供大家參考。具體分析如下:

相同點:

1、都是為了重用性(reusebility)——軟體工程中一個非常重要的目標。

2、C#裡面的名稱空間和java中的包都屬於訪問許可權的控制機制。

不同點:

1、C#名稱空間只是一種邏輯上的結構,它允許所組織的類檔案的物理存放位置與邏輯結構不一致,而Java中類檔案的物理結構必須與邏輯結構一致。

2、Java的package本身沒有子包的概念,所有package都是並列的關係,沒有誰包含誰的問題。比如:org.dominoo.action和org.dominoo.action.asl之間絕對沒有包與子包的關係。它們是各自獨立的包,各自擁有自己的class/interface的集合。在org.dominoo.action.asl的某個java檔案裡,如果想引用org.dominoo.action裡的某個class/interface,則必須import org.dominoo.action。

C++/C#的namespace方案則不然,一個namespace可以有自己的sub-namespace,我們不妨將namespace也稱為package,那麼C++/C#的package之間就可能存在包與子包的關係.

3、Java中使用import語句而C#中使用using namespace語句。

6.1.1 包圖

包圖是描述包及其關係的圖。與所有UML的其它圖一樣,包圖可以包括註釋、約束。包間的關係有依賴關係和泛化關係。上圖是一個典型的包圖。

6.1.2 包的作用

在面向物件軟體開發的過程中,類顯然是構建整個系統的基本元素。但是對於大型的軟體系統而言,其包含的類將是成百上千,再加上類間的關聯關係、多重性等,必然是大大超出了人們對系統的理解和處理能力。為了便於管理這些類,我們引入了“包”這種分組元素。

包的作用是:
1.對語義上相關的元素進行分組。如,把功能相關的用例放在一個包中。
2.提供配置管理單元。如,以包為單位,對軟體進行安裝和配置。
3.在設計時,提供並行工作的單元。如,在設計階段,多個設計小組,可以同時對幾個相互獨立包中的類進行詳細設計。
4.提供封裝的名稱空間,同一個包中,其元素的名稱必須惟一。

6.1.3 包中的元素

在包中可以擁有各種其它元素,包括類、介面、構件、節點、協作、用例,甚至是其它子包或圖 。一個元素只能屬於一個包。

命名方式

每個包必須有一個與其他包相區別的名稱,包的名字是一個字串:

  • 簡單名:僅含一個簡單的名稱。

  • 路徑名::以包所位於的外圍包的名字作為字首的包名

    1. 當不需要顯示包的內容時,將包的名字放入主方框內;

    2. 需要顯示內容時包的名字放入左上角的小方框中,將內容放入主方框內。

    3. 標以 {global} 的包叫通用包,表示系統的所有其他包都依賴於該包。

UML中,用資料夾符號來表示一個包。包由一個矩形表示,它包含2欄。下面是最常見的幾種包的表示法

6.2.1 包的名稱

每個包必須有一個與其他包相區別的名稱。標識包名稱的格式有兩種:簡單名和全名。
其中,簡單名僅包含包一個簡單的名稱;全名是用該包的外圍包的名字作為字首,加上包本身的名字。
例如,Rose常用表示方法中,其包名UI就是一個簡單名。而包System.Web.UI才是一個完整帶路徑的名稱,表示UI這個包是位於System.Web名稱空間中的。如圖所示

6.2.2 包的元素

在一個包中可以擁有各種其他元素,包括類、介面、構件、節點、協作、用例,甚至是其他包或圖。這是一種組成關係,意味著元素是在這個包中宣告的,因此一個元素只能屬於一個包。
每一個包就意味著一個獨立的名稱空間,因此,兩個不同的包,可以具有相同的元素名,但由於所位於的包名不同,因此其全名仍然是不同的。
在包中表擁有的元素時,有兩種方法:一種是在第二欄中列出所屬元素名,一種是在第二欄中畫出所屬元素的圖形表示(參見下圖)。

6.2.3 包元素的可見性

像類中的屬性和方法一樣,包中的元素也有可見性,包內元素的可見性控制了包外部元素訪問包內部元素的許可權。
包的可見性有3種:可以用“+”來表示“public”,即,該元素是共有的;用“#”來表示“protected”, 即該元素是保護的,用“-”來表示“private”, 即,該元素是私有的。

包內元素的可見性,標識了外部元素訪問包內元素的許可權。表6-1列出了可見性與訪問許可權的關係。

表6-1 可見性與訪問許可權(假設包B中的元素訪問包A中的元素)

6.2.4 包的構造型

為了表示包的新特性,用構造型來描述包的新特徵。包的構造型有5種,下面分別說明。
1.《system》構造型:《system》構造型的包表示整個系統.
2.《subsystem》構造型:《subsystem》構造型的包則表示正在建模的系統中某個獨立的子系統.
3.《facade》構造型:只是某個其它包的檢視,它主要用來為其它一些複雜的包提供簡略檢視
4.《stub》構造型:是一個代理包,它服務於某個其他包的公共內容,這通常應用於分散式系統的建模中 .
5.《framework》構造型:用來表示一個框架的,框架是一個領域內的應用系統提供可擴充模板的體系結構模式

6.3 包圖中的關係

包圖中的關係有2種:依賴關係、泛化關係。

6.3.1 依賴關係

1.《use》關係
《use》關係是一種預設的依賴關係 ,說明客戶包(箭尾端的包)中的元素以某種方式使用提供者包(箭頭端的包)的公共元素,也就是說客戶包依賴於提供者包。如果沒有指明依賴型別,則預設為《USE》關係。
例如在圖中,有兩個《USE》依賴,Client包將通過Server包來完成Order的儲存,而Server包使用System.Data.SqlClient包來實現資料庫的儲存。

2.《import》關係
《import》關係:最普遍的包依賴型別,說明提供者包的名稱空間將被新增到客戶包的名稱空間中,客戶包中的元素也能夠訪問提供者包的所有公共元素。
《import》關係使名稱空間合併,當提供者包中的元素具有與客戶包中的元素相同的名稱時,將會導致名稱空間的衝突。這也意味著,當客戶包的元素引用提供者包的元素時,將無需使用全稱,只需使用元素名稱即可。
例如在上圖中,Client包引用了(import)了Rule包,Rule包又引用了GUI包。同時,這還表示Client包間接引用了GUI包。

3.《access》關係
如果只想使用提供者包中的元素,而不想將兩個包合併,則應使用該關係。在客戶包中必須使用路徑名,才能訪問提供者包中的所有公共元素。

4.《trace》關係
想表示一個包到另一個包的歷史發展,則需要使用《trace》關係來表示

6.3.2 泛化關係

包間的泛化關係類似於類間的泛化關係,使用一般包的地方,可以用特殊包代替。
在系統設計中,對某一個特定的功能,有多種實現方法。例如,實現多資料庫支援;實現B/S和C/S雙介面。這時就需要定義一些高層次的“抽象包”和實現高層次功能的“實現包”。
在抽象包中定義一些介面和抽象類,在實現包中,定義一些包含實現這些抽象類和介面的具體類。例如在上圖中,說明GUI有兩種風格:一種是基於WinForm的C/S風格,一種是WebForm的B/S風格。
需要注意的是,在《在UML使用者手冊》中將其歸為泛化關係,而在《UML精粹》中卻將其看作是實現關係。

6.4 閱讀包圖

閱讀包圖的方法:
1.瞭解每個包的語義,它包含的元素語義。
2.理解包間的關係。
3.找到依賴關係複雜的包,從最複雜的包開始閱讀,然後以此是簡單的包。
例如,閱讀下面的包圖。

對上面包的理解如下:
(1)根據《use》關係可以發現Client包使用Server包,Server包使用System.Data.SqlClient包,根據它們所包含的元素語義,可以得知Client包負責Order(訂單)的輸入,並通過Server包來管理使用者的登入(LoggingService)和資料庫儲存(DataBase);而Server包還通過.Net的SQL SERVER訪問工具包,來實現與資料庫的連線和通訊。
(2)看《import》關係,從RULE包所包含的元素語義可知,該包負責處理一些規則,並引用一個具體的窗體(Window);而Client包通過引用RULE來實現整個窗體和表單的顯示,輸入等,並且還將暫存Order(訂單)資訊。
(3)接著來看包的泛化關係。GUI有兩個具體實現:一個是針對C/S的WindowsGUI,一個是實現B/S的WebGUI.

6.5 建立包圖

繪製包圖的基本過程主要有三個步驟:第一,尋找包;第二,確定包之間的關係;第三,標出包內元素的可見性。
繪製包圖的“最小化系統間的耦合關係”的原則:
最大限度減少包之間的依賴,包封裝時,避免包之間的迴圈依賴;最小化每個包的public、protected元素的個數,最大化每個包中private元素的個數。

6.5.1 尋找包

通過把具有很強語義聯絡的建模元素分組,找出分析包。分析包必須反映元素的真實的語義分組,而不僅是邏輯架構的理想檢視。
我們以物件模型和用例模型為依據,把關係緊密的類分到同一個包中,把關係鬆散的類分到不同的包中。
1.標識候選包的原則:
(1).把類圖中關係緊密的類放到一個包中;
(2).在類繼承類層次中,把不同層次的類放在不同的包中。
也可以把用例模型作為包的來源。然而,用例橫跨分析包是非常普遍的——一個用例可以由幾個不同包中的類實現。

2.調整候選包
在已經識別一組候選包後,然後減少包間依賴,最小化每個包的public、protected元素的個數,最大化每個包中private元素的個數。做法是:
(1).在包間移動類;
(2).新增包或刪除包。

良好包結構的關鍵是包內高內聚,包間低耦合。

通常,當建立分析包模型時,應該儘量使包模型簡單。獲得正確的包集合比使用諸如包泛化和依賴構造型的特徵更加重要,這些特徵可以以後再新增,僅當使用諸如包泛化和依賴構造型的特徵使得模型更加容易理解時,才使用這些包整理技術。除了保持簡單,還應該避免巢狀包。物件在巢狀包結構中埋藏得越深,模型變得越晦澀。

作為經驗法則,希望每個包具有4~10個分析類。然而,對於所有的經驗法則,卻存在例外,如果打破某個法則使得模型更加清晰,就採用這個法則!有時,你必須引入只帶有一個或者兩個類的包,因為你需要斷開包模型中的迴圈依賴。在這種情況下,這是完全合理的。

6.5.2 消除迴圈包依賴

應該儘量避免包模型中的迴圈依賴。如果包A以某種方式依賴包B,並且包B以某種方式依賴包A,就應該合併這兩個包,這是消除迴圈依賴非常有效的方法。但是經常起作用的、更好的方法是,努力分解公共元素成為第三個包C。重新計算依賴關係,以消除迴圈依賴。示例顯示在圖中。
很多建模工具允許自動驗證包間依賴。如果一個包中的元素訪問另一個包中的元素,但兩個包間卻沒有依賴關係,那麼工具產生訪問衝突列表。
在分析模型中,不可能建立沒有訪問衝突的包圖。

6.6 包圖建模

包圖主要用於兩種不同層次的用途:一是對成組元素建模;二是對體系結構建模。

6.6.1 對成組元素建模

對成組元素進行建模可以說是包圖最常見的用途,它將建模元素組織成組,然後對組進行命名,在對成組元素建模時,應遵循以下幾個策略:
每個包都應該是由在概念上,語義上相互接近的元素組成。
對於每個包,找出應標記為公共的元素,但應儘可能地少。
一般使用預設的《use》構造型,在實現類時,才用《import》構造型代替《use》構造型。
採用泛化來對特殊包進行建模。
在構建包模型時,注意,在包中只標明對每個包起核心作用的元素;另外業可以標識每個包的文件標記值,以使其更加清晰。

6.6.2 對體系結構建模

體系結構是一個軟體系統的核心邏輯結構,常用的體系結構模式包括分層、MVC、管道、黑板、微核心等,而在應用軟體中,分層和MVC是最常見的兩種結構。
在分層的體系結構中,最常見的劃分是表示層(present)、邏輯層(business或domain)、資料層(包括資料訪問、日記等)。如果採用分層體系結構,我們就把每一層用一個包來表示,如圖所示

圖 用包分層