西部村里人

          常用鏈接

          統(tǒng)計(jì)

          其它BLOG

          最新評(píng)論

          Hibernate對(duì)象關(guān)聯(lián)--UML基礎(chǔ)知識(shí)、XDoclet--- 1 UML基礎(chǔ)部分(來(lái)自UMLchina網(wǎng)站)


          UML軟件工程組織

          UML 基礎(chǔ):類圖
          選自:IBM
          這是關(guān)于統(tǒng)一建模語(yǔ)言、即UML 里采用的基本圖的一系列文章的一部分。在我 先前關(guān)于序列圖的文章 里,我把重點(diǎn)從 UML 1.4 版,轉(zhuǎn)移到 OMG的采用UML 2.0版草案規(guī)范(又稱為UML 2)。在這篇文章中,我將會(huì)討論結(jié)構(gòu)圖,這是已經(jīng)在 UML 2 中提出的一種新圖種類。由于本系列文章的目的是使人們了解記號(hào)元素及它們的含意,該文主要關(guān)注類圖。你很快就會(huì)知道這樣做的理由。隨后的文章將會(huì)覆蓋結(jié)構(gòu)范疇中包含的其它圖。

          我也想提醒讀者,這一系列文章是關(guān)于 UML 記號(hào)元素的,所以這些文章并不意味著為建模的最好方式提供指導(dǎo)方針,或是該如何決定哪些內(nèi)容應(yīng)該首先被建模。相反的,該文及本系列文章的目的主要是幫助大家對(duì)于記號(hào)元素 -- 語(yǔ)法和含義有一個(gè)基本的理解。借由這些知識(shí),你應(yīng)該可以閱讀圖,并使用正確的記號(hào)元素創(chuàng)建你自己的圖。

          這篇文章假定你對(duì)面向?qū)ο蟮脑O(shè)計(jì)已經(jīng)有了基本的理解。你們當(dāng)中如果有人需要一些面向?qū)ο蟾拍畹膸椭敲纯梢栽L問(wèn)http://java.sun.com/docs/books/tutorial/java/concepts/,來(lái)獲得Sun公司關(guān)于面向?qū)ο缶幊痰暮?jiǎn)短指導(dǎo)。閱讀 “什么是類?”和 什么是繼承?” 章節(jié),將提供給你足夠的理解,并對(duì)該文的閱讀會(huì)有所幫助。另外,David Taylor的書(shū)《 Object-Oriented Technologies: A Manager's Guide》提供了面向?qū)ο笤O(shè)計(jì)的優(yōu)秀,高水平的說(shuō)明,而無(wú)需對(duì)計(jì)算機(jī)編程有高深的理解。

          UML 2 中的陰和陽(yáng)
          在 UML 2 中有二種基本的圖范疇:結(jié)構(gòu)圖和行為圖。每個(gè) UML 圖都屬于這二個(gè)圖范疇。結(jié)構(gòu)圖的目的是顯示建模系統(tǒng)的靜態(tài)結(jié)構(gòu)。它們包括類,組件和(或)對(duì)象圖。另一方面,行為圖顯示系統(tǒng)中的對(duì)象的動(dòng)態(tài)行為,包括如對(duì)象的方法,協(xié)作和活動(dòng)之類的內(nèi)容。行為圖的實(shí)例是活動(dòng)圖,用例圖和序列圖。

          大體上的結(jié)構(gòu)圖
          如同我所說(shuō)的,結(jié)構(gòu)圖顯示建模系統(tǒng)的靜態(tài)結(jié)構(gòu)。關(guān)注系統(tǒng)的元件,無(wú)需考慮時(shí)間。在系統(tǒng)內(nèi),靜態(tài)結(jié)構(gòu)通過(guò)顯示類型和它們的實(shí)例進(jìn)行傳播。除了顯示系統(tǒng)類型和它們的實(shí)例,結(jié)構(gòu)圖至少也顯示了這些元素間的一些關(guān)系,可能的話,甚至也顯示它們的內(nèi)部結(jié)構(gòu)。

          貫穿整個(gè)軟件生命周期,結(jié)構(gòu)圖對(duì)于各種團(tuán)隊(duì)成員都是有用的。一般而言,這些圖支持設(shè)計(jì)驗(yàn)證,和個(gè)體與團(tuán)隊(duì)間的設(shè)計(jì)交流。舉例來(lái)說(shuō),業(yè)務(wù)分析師可以使用類或?qū)ο髨D,來(lái)為當(dāng)前的資產(chǎn)和資源建模,例如分類賬,產(chǎn)品或地理層次。架構(gòu)師可以使用組件和部署圖,來(lái)測(cè)試/確認(rèn)他們的設(shè)計(jì)是否充分。開(kāi)發(fā)者可以使用類圖,來(lái)設(shè)計(jì)并為系統(tǒng)的代碼(或即將成為代碼的)類寫文檔。

          特殊的類圖

          UML 2 把結(jié)構(gòu)圖看成一個(gè)分類;這里并不存在稱為“結(jié)構(gòu)圖”的圖。然而,類圖提供結(jié)構(gòu)圖類型的一個(gè)主要實(shí)例,并為我們提供一組記號(hào)元素的初始集,供所有其它結(jié)構(gòu)圖使用。由于類圖是如此基本,本文的剩余部分將會(huì)把重點(diǎn)集中在類圖記號(hào)集。在本文的結(jié)尾,你將對(duì)于如何畫UML 2類圖有所了解,而且對(duì)于理解在后面文章中將涉及的其他結(jié)構(gòu)圖有一個(gè)穩(wěn)固的基礎(chǔ)。

          基礎(chǔ)
          如先前所提到的,類圖的目的是顯示建模系統(tǒng)的類型。在大多數(shù)的 UML 模型中這些類型包括:



          • 接口

          • 數(shù)據(jù)類型

          • 組件

          UML 為這些類型起了一個(gè)特別的名字:“分類器”。通常地,你可以把分類器當(dāng)做類,但在技術(shù)上,分類器是更為普遍的術(shù)語(yǔ),它還是引用上面的其它三種類型為好。

          類名

          類的 UML 表示是一個(gè)長(zhǎng)方形,垂直地分為三個(gè)區(qū),如圖 1 所示。頂部區(qū)域顯示類的名字。中間的區(qū)域列出類的屬性。底部的區(qū)域列出類的操作。當(dāng)在一個(gè)類圖上畫一個(gè)類元素時(shí),你必須要有頂端的區(qū)域,下面的二個(gè)區(qū)域是可選擇的(當(dāng)圖描述僅僅用于顯示分類器間關(guān)系的高層細(xì)節(jié)時(shí),下面的兩個(gè)區(qū)域是不必要的)。圖 1 顯示一個(gè)航線班機(jī)如何作為 UML 類建模。正如我們所能見(jiàn)到的,名字是 Flight,我們可以在中間區(qū)域看到Flight類的3個(gè)屬性:flightNumber,departureTime 和 flightDuration。在底部區(qū)域中我們可以看到Flight類有兩個(gè)操作:delayFlight 和 getArrivalTime。

          圖 1: Flight類的類圖

          圖 1: Flight類的類圖

           

          類屬性列表

          類的屬性節(jié)(中部區(qū)域)在分隔線上列出每一個(gè)類的屬性。屬性節(jié)是可選擇的,要是一用它,就包含類的列表顯示的每個(gè)屬性。該線用如下格式:

          name : attribute type
          flightNumber : Integer

          繼續(xù)我們的Flight類的例子,我們可以使用屬性類型信息來(lái)描述類的屬性,如表 1 所示。

          表 1:具有關(guān)聯(lián)類型的Flight類的屬性名字

          屬性名稱 屬性類型
          flightNumber Integer
          departureTime Date
          flightDuration Minutes

          在業(yè)務(wù)類圖中,屬性類型通常與單位相符,這對(duì)于圖的可能讀者是有意義的(例如,分鐘,美元,等等)。然而,用于生成代碼的類圖,要求類的屬性類型必須限制在由程序語(yǔ)言提供的類型之中,或包含于在系統(tǒng)中實(shí)現(xiàn)的、模型的類型之中。

          在類圖上顯示具有默認(rèn)值的特定屬性,有時(shí)是有用的(例如,在銀行賬戶應(yīng)用程序中,一個(gè)新的銀行賬戶會(huì)以零為初始值)。UML 規(guī)范允許在屬性列表節(jié)中,通過(guò)使用如下的記號(hào)作為默認(rèn)值的標(biāo)識(shí):

          name : attribute type = default value

          舉例來(lái)說(shuō):

          balance : Dollars = 0

          顯示屬性默認(rèn)值是可選擇的;圖 2 顯示一個(gè)銀行賬戶類具有一個(gè)名為 balance的類型,它的默認(rèn)值為0。

          圖 2:顯示默認(rèn)為0美元的balance屬性值的銀行賬戶類圖。

          圖 2:顯示默認(rèn)為0美元的balance屬性值的銀行賬戶類圖。

           

          類操作列表

          類操作記錄在類圖長(zhǎng)方形的第三個(gè)(最低的)區(qū)域中,它也是可選擇的。和屬性一樣,類的操作以列表格式顯示,每個(gè)操作在它自己線上。操作使用下列記號(hào)表現(xiàn):

          	name(parameter list) : type of value returned

          下面的表 2 中Flight類操作的映射。

          表 2:從圖 2 映射的Flight類的操作

          操作名稱 返回參數(shù) 值類型
          delayFlight
          Name Type
          numberOfMinutes Minutes
          N/A
          getArrivalTime N/A Date

          圖3顯示,delayFlight 操作有一個(gè)Minutes類型的輸入?yún)?shù) -- numberOfMinutes。然而,delayFlight 操作沒(méi)有返回值。1 當(dāng)一個(gè)操作有參數(shù)時(shí),參數(shù)被放在操作的括號(hào)內(nèi);每個(gè)參數(shù)都使用這樣的格式:“參數(shù)名:參數(shù)類型”。

          圖 3:Flight類操作參數(shù),包括可選擇的“in”標(biāo)識(shí)。

          圖 3:Flight類操作參數(shù),包括可選擇的“in”標(biāo)識(shí)。

           

          當(dāng)文檔化操作參數(shù)時(shí),你可能使用一個(gè)可選擇的指示器,以顯示參數(shù)到操作的輸入?yún)?shù)、或輸出參數(shù)。這個(gè)可選擇的指示器以“in”或“out”出現(xiàn),如圖3中的操作區(qū)域所示。一般來(lái)說(shuō),除非將使用一種早期的程序編程語(yǔ)言,如Fortran ,這些指示器可能會(huì)有所幫助,否則它們是不必要的。然而,在 C++和Java中,所有的參數(shù)是“in”參數(shù),而且按照UML規(guī)范,既然“in”是參數(shù)的默認(rèn)類型,大多數(shù)人將會(huì)遺漏輸入/輸出指示器。

          繼承

          在面向?qū)ο蟮脑O(shè)計(jì)中一個(gè)非常重要的概念,繼承,指的是一個(gè)類(子類)繼承另外的一個(gè)類(超類)的同一功能,并增加它自己的新功能(一個(gè)非技術(shù)性的比喻,想象我繼承了我母親的一般的音樂(lè)能力,但是在我的家里,我是唯一一個(gè)玩電吉他的人)的能力。為了在一個(gè)類圖上建模繼承,從子類(要繼承行為的類)拉出一條閉合的,單鍵頭(或三角形)的實(shí)線指向超類。考慮銀行賬戶的類型:圖 4 顯示 CheckingAccount 和 SavingsAccount 類如何從 BankAccount 類繼承而來(lái)。

          圖 4: 繼承通過(guò)指向超類的一條閉合的,單箭頭的實(shí)線表示。

          圖 4: 繼承通過(guò)指向超類的一條閉合的,單箭頭的實(shí)線表示。

           

          在圖 4 中,繼承關(guān)系由每個(gè)超類的單獨(dú)的線畫出,這是在IBM Rational Rose和IBM Rational XDE中使用的方法。然而,有一種稱為 樹(shù)標(biāo)記的備選方法可以畫出繼承關(guān)系。當(dāng)存在兩個(gè)或更多子類時(shí),如圖 4 中所示,除了繼承線象樹(shù)枝一樣混在一起外,你可以使用樹(shù)形記號(hào)。圖 5 是重繪的與圖 4 一樣的繼承,但是這次使用了樹(shù)形記號(hào)。

          圖 5: 一個(gè)使用樹(shù)形記號(hào)的繼承實(shí)例

          圖 5: 一個(gè)使用樹(shù)形記號(hào)的繼承實(shí)例

           

          抽象類及操作
          細(xì)心的讀者會(huì)注意到,在圖 4 和 圖5 中的圖中,類名BankAccount和withdrawal操作使用斜體。這表示,BankAccount 類是一個(gè)抽象類,而withdrawal方法是抽象的操作。換句話說(shuō),BankAccount 類使用withdrawal規(guī)定抽象操作,并且CheckingAccount 和 SavingsAccount 兩個(gè)子類都分別地執(zhí)行它們各自版本的操作。

          然而,超類(父類)不一定要是抽象類。標(biāo)準(zhǔn)類作為超類是正常的。

          關(guān)聯(lián)
          當(dāng)你系統(tǒng)建模時(shí),特定的對(duì)象間將會(huì)彼此關(guān)聯(lián),而且這些關(guān)聯(lián)本身需要被清晰地建模。有五種關(guān)聯(lián)。在這一部分中,我將會(huì)討論它們中的兩個(gè) -- 雙向的關(guān)聯(lián)和單向的關(guān)聯(lián),而且我將會(huì)在Beyond the basics部分討論剩下的三種關(guān)聯(lián)類型。請(qǐng)注意,關(guān)于何時(shí)該使用每種類型關(guān)聯(lián)的詳細(xì)討論,不屬于本文的范圍。相反的,我將會(huì)把重點(diǎn)集中在每種關(guān)聯(lián)的用途,并說(shuō)明如何在類圖上畫出關(guān)聯(lián)。

          雙向(標(biāo)準(zhǔn))的關(guān)聯(lián)
          關(guān)聯(lián)是兩個(gè)類間的聯(lián)接。關(guān)聯(lián)總是被假定是雙向的;這意味著,兩個(gè)類彼此知道它們間的聯(lián)系,除非你限定一些其它類型的關(guān)聯(lián)。回顧一下Flight 的例子,圖 6 顯示了在Flight類和Plane類之間的一個(gè)標(biāo)準(zhǔn)類型的關(guān)聯(lián)。

          圖 6:在一個(gè)Flight類和Plane類之間的雙向關(guān)聯(lián)的實(shí)例

          圖 6:在一個(gè)Flight類和Plane類之間的雙向關(guān)聯(lián)的實(shí)例

           

          一個(gè)雙向關(guān)聯(lián)用兩個(gè)類間的實(shí)線表示。在線的任一端,你放置一個(gè)角色名和多重值。圖 6 顯示Flight與一個(gè)特定的Plane相關(guān)聯(lián),而且Flight類知道這個(gè)關(guān)聯(lián)。因?yàn)榻巧訮lane類表示,所以Plane承擔(dān)關(guān)聯(lián)中的“assignedPlane”角色。緊接于Plane類后面的多重值描述0...1表示,當(dāng)一個(gè)Flight實(shí)體存在時(shí),可以有一個(gè)或沒(méi)有Plane與之關(guān)聯(lián)(也就是,Plane可能還沒(méi)有被分配)。圖 6 也顯示Plane知道它與Flight類的關(guān)聯(lián)。在這個(gè)關(guān)聯(lián)中,F(xiàn)light承擔(dān)“assignedFlights”角色;圖 6 的圖告訴我們,Plane實(shí)體可以不與flight關(guān)聯(lián)(例如,它是一架全新的飛機(jī))或與沒(méi)有上限的flight(例如,一架已經(jīng)服役5年的飛機(jī))關(guān)聯(lián)。

          由于對(duì)那些在關(guān)聯(lián)尾部可能出現(xiàn)的多重值描述感到疑惑,下面的表3列出了一些多重值及它們含義的例子。

          表 3: 多重值和它們的表示

          可能的多重值描述
          表示 含義
          0..1 0個(gè)或1個(gè)
          1 只能1個(gè)
          0..* 0個(gè)或多個(gè)
          * 0個(gè)或多個(gè)
          1..* 1個(gè)或我個(gè)
          3 只能3個(gè)
          0..5 0到5個(gè)
          5..15 5到15個(gè)

          單向關(guān)聯(lián)
          在一個(gè)單向關(guān)聯(lián)中,兩個(gè)類是相關(guān)的,但是只有一個(gè)類知道這種聯(lián)系的存在。圖 7 顯示單向關(guān)聯(lián)的透支財(cái)務(wù)報(bào)告的一個(gè)實(shí)例。

          圖 7: 單向關(guān)聯(lián)一個(gè)實(shí)例:OverdrawnAccountsReport 類 BankAccount 類,而 BankAccount 類則對(duì)關(guān)聯(lián)一無(wú)所知。

          圖 7: 單向關(guān)聯(lián)一個(gè)實(shí)例:OverdrawnAccountsReport 類 BankAccount 類,而 BankAccount 類則對(duì)關(guān)聯(lián)一無(wú)所知。

           

          一個(gè)單向的關(guān)聯(lián),表示為一條帶有指向已知類的開(kāi)放箭頭(不關(guān)閉的箭頭或三角形,用于標(biāo)志繼承)的實(shí)線。如同標(biāo)準(zhǔn)關(guān)聯(lián),單向關(guān)聯(lián)包括一個(gè)角色名和一個(gè)多重值描述,但是與標(biāo)準(zhǔn)的雙向關(guān)聯(lián)不同的時(shí),單向關(guān)聯(lián)只包含已知類的角色名和多重值描述。在圖 7 中的例子中,OverdrawnAccountsReport 知道 BankAccount 類,而且知道 BankAccount 類扮演“overdrawnAccounts”的角色。然而,和標(biāo)準(zhǔn)關(guān)聯(lián)不同,BankAccount 類并不知道它與 OverdrawnAccountsReport 相關(guān)聯(lián)。2

          軟件包
          不可避免,如果你正在為一個(gè)大的系統(tǒng)或大的業(yè)務(wù)領(lǐng)域建模,在你的模型中將會(huì)有許多不同的分類器。管理所有的類將是一件令人生畏的任務(wù);所以,UML 提供一個(gè)稱為 軟件包的組織元素。軟件包使建模者能夠組織模型分類器到名字空間中,這有些象文件系統(tǒng)中的文件夾。把一個(gè)系統(tǒng)分為多個(gè)軟件包使系統(tǒng)變成容易理解,尤其是在每個(gè)軟件包都表現(xiàn)系統(tǒng)的一個(gè)特定部分時(shí)。3

          在圖中存在兩種方法表示軟件包。并沒(méi)有規(guī)則要求使用哪種標(biāo)記,除了用你個(gè)人的判斷:哪種更便于閱讀你畫的類圖。兩種方法都是由一個(gè)較小的長(zhǎng)方形(用于定位)嵌套在一個(gè)大的長(zhǎng)方形中開(kāi)始的,如圖 8 所示。但是建模者必須決定包的成員如何表示,如下:

          • 如果建模者決定在大長(zhǎng)方形中顯示軟件包的成員,則所有的那些成員4 需要被放置在長(zhǎng)方形里面。另外,所有軟件包的名字需要放在軟件包的較小長(zhǎng)方形之內(nèi)(如圖 8 的顯示)。

          • 如果建模者決定在大的長(zhǎng)方形之外顯示軟件包成員,則所有將會(huì)在圖上顯示的成員都需要被置于長(zhǎng)方形之外。為了顯示屬于軟件包的分類器屬于,從每個(gè)分類器畫一條線到里面有加號(hào)的圓周,這些圓周粘附在軟件包之上(圖9)。
          圖 8:在軟件包的長(zhǎng)方形內(nèi)顯示軟件包成員的軟件包元素例子

          圖 8:在軟件包的長(zhǎng)方形內(nèi)顯示軟件包成員的軟件包元素例子

           

          圖 9:一個(gè)通過(guò)連接線表現(xiàn)軟件包成員的軟件包例子

          圖 9:一個(gè)通過(guò)連接線表現(xiàn)軟件包成員的軟件包例子

           

          了解基礎(chǔ)重要性

          在 UML 2 中,了解類圖的基礎(chǔ)更為重要。這是因?yàn)轭悎D為所有的其他結(jié)構(gòu)圖提供基本的構(gòu)建塊。如組件或?qū)ο髨D(僅僅是舉了些例子)。

          超過(guò)基礎(chǔ)
          到此為止,我已經(jīng)介紹了類圖的基礎(chǔ),但是請(qǐng)繼續(xù)往下讀!在下面的部分中,我將會(huì)引導(dǎo)你到你會(huì)使用的類圖的更重要的方面。這些包括UML 2 規(guī)范中的接口,其它的三種關(guān)聯(lián)類型,可見(jiàn)性和其他補(bǔ)充。

          接口
          在本文的前面,我建議你以類來(lái)考慮分類器。事實(shí)上,分類器是一個(gè)更為一般的概念,它包括數(shù)據(jù)類型和接口。

          關(guān)于何時(shí)、以及如何高效地在系統(tǒng)結(jié)構(gòu)圖中使用數(shù)據(jù)類型和接口的完整討論,不在本文的討論范圍之內(nèi)。既然這樣,我為什么要在這里提及數(shù)據(jù)類型和接口呢?你可能想在結(jié)構(gòu)圖上模仿這些分類器類型,在這個(gè)時(shí)候,使用正確的記號(hào)來(lái)表示,或者至少知道這些分類器類型是重要的。不正確地繪制這些分類器,很有可能將使你的結(jié)構(gòu)圖讀者感到混亂,以后的系統(tǒng)將不能適應(yīng)需求。

          一個(gè)類和一個(gè)接口不同:一個(gè)類可以有它形態(tài)的真實(shí)實(shí)例,然而一個(gè)接口必須至少有一個(gè)類來(lái)實(shí)現(xiàn)它。在 UML 2 中,一個(gè)接口被認(rèn)為是類建模元素的特殊化。因此,接口就象類那樣繪制,但是長(zhǎng)方形的頂部區(qū)域也有文本“interface”,如圖 10 所示。5

          圖 10:Professor類和Student類實(shí)現(xiàn)Person接口的類圖實(shí)例

          圖 10:Professor類和Student類實(shí)現(xiàn)Person接口的類圖實(shí)例

           

          在圖 10 中顯示的圖中,Professor和Student類都實(shí)現(xiàn)了Person的接口,但并不從它繼承。我們知道這一點(diǎn)是由于下面兩個(gè)原因:1) Person對(duì)象作為接口被定義 -- 它在對(duì)象的名字區(qū)域中有“interface”文本,而且我們看到由于Professor和Student對(duì)象根據(jù)畫類對(duì)象的規(guī)則(在它們的名字區(qū)域中沒(méi)有額外的分類器文本)標(biāo)示,所以它們是 對(duì)象。 2) 我們知道繼承在這里沒(méi)有被顯示,因?yàn)榕c帶箭頭的線是點(diǎn)線而不是實(shí)線。如圖 10 所示,一條帶有閉合的單向箭頭的點(diǎn) 線意味著實(shí)現(xiàn)(或?qū)嵤徽缥覀冊(cè)趫D 4 中所見(jiàn)到的,一條帶有閉合單向箭頭的實(shí)線表示繼承。

          更多的關(guān)聯(lián)
          在上面,我討論了雙向關(guān)聯(lián)和單向關(guān)聯(lián)。現(xiàn)在,我將會(huì)介紹剩下的三種類型的關(guān)聯(lián)。

          關(guān)聯(lián)類
          在關(guān)聯(lián)建模中,存在一些情況下,你需要包括其它類,因?yàn)樗岁P(guān)于關(guān)聯(lián)的有價(jià)值的信息。對(duì)于這種情況,你會(huì)使用 關(guān)聯(lián)類 來(lái)綁定你的基本關(guān)聯(lián)。關(guān)聯(lián)類和一般類一樣表示。不同的是,主類和關(guān)聯(lián)類之間用一條相交的點(diǎn)線連接。圖 11 顯示一個(gè)航空工業(yè)實(shí)例的關(guān)聯(lián)類。

          圖 11:增加關(guān)聯(lián)類 MileageCredit

          圖 11:增加關(guān)聯(lián)類 MileageCredit

           

          在圖 11 中顯示的類圖中,在Flight類和 FrequentFlyer 類之間的關(guān)聯(lián),產(chǎn)生了稱為 MileageCredit的關(guān)聯(lián)類。這意味當(dāng)Flight類的一個(gè)實(shí)例關(guān)聯(lián)到 FrequentFlyer 類的一個(gè)實(shí)例時(shí),將會(huì)產(chǎn)生 MileageCredit 類的一個(gè)實(shí)例。

          聚合
          聚合是一種特別類型的關(guān)聯(lián),用于描述“總體到局部”的關(guān)系。在基本的聚合關(guān)系中, 部分類 的生命周期獨(dú)立于 整體類 的生命周期。

          舉例來(lái)說(shuō),我們可以想象, 是一個(gè)整體實(shí)體,而 車輪 輪胎是整輛車的一部分。輪胎可以在安置到車時(shí)的前幾個(gè)星期被制造,并放置于倉(cāng)庫(kù)中。在這個(gè)實(shí)例中,Wheel類實(shí)例清楚地獨(dú)立地Car類實(shí)例而存在。然而,有些情況下, 部分 類的生命周期并 獨(dú)立于 整體 類的生命周期 -- 這稱為合成聚合。舉例來(lái)說(shuō),考慮公司與部門的關(guān)系。 公司和部門 都建模成類,在公司存在之前,部門不能存在。這里Department類的實(shí)例依賴于Company類的實(shí)例而存在。

          讓我們更進(jìn)一步探討基本聚合和組合聚合。

          基本聚合
          有聚合關(guān)系的關(guān)聯(lián)指出,某個(gè)類是另外某個(gè)類的一部分。在一個(gè)聚合關(guān)系中,子類實(shí)例可以比父類存在更長(zhǎng)的時(shí)間。為了表現(xiàn)一個(gè)聚合關(guān)系,你畫一條從父類到部分類的實(shí)線,并在父類的關(guān)聯(lián)末端畫一個(gè)未填充棱形。圖 12 顯示車和輪胎間的聚合關(guān)系的例子。

          圖 12: 一個(gè)聚合關(guān)聯(lián)的例子

          圖 12: 一個(gè)聚合關(guān)聯(lián)的例子

           

          組合聚合
          組合聚合關(guān)系是聚合關(guān)系的另一種形式,但是子類實(shí)例的生命周期依賴于父類實(shí)例的生命周期。在圖13中,顯示了Company類和Department類之間的組合關(guān)系,注意組合關(guān)系如聚合關(guān)系一樣繪制,不過(guò)這次菱形是被填充的。

          圖 13: 一個(gè)組合關(guān)系的例子

          圖 13: 一個(gè)組合關(guān)系的例子

           

          在圖 13 中的關(guān)系建模中,一個(gè)Company類實(shí)例至少總有一個(gè)Department類實(shí)例。因?yàn)殛P(guān)系是組合關(guān)系,當(dāng)Company實(shí)例被移除/銷毀時(shí),Department實(shí)例也將自動(dòng)地被移除/銷毀。組合聚合的另一個(gè)重要功能是部分類只能與父類的實(shí)例相關(guān)(舉例來(lái)說(shuō),我們例子中的Company類)。

          反射關(guān)聯(lián)
          現(xiàn)在我們已經(jīng)討論了所有的關(guān)聯(lián)類型。就如你可能注意到的,我們的所有例子已經(jīng)顯示了兩個(gè)不同類之間的關(guān)系。然而,類也可以使用反射關(guān)聯(lián)與它本身相關(guān)聯(lián)。起先,這可能沒(méi)有意義,但是記住,類是抽象的。圖 14 顯示一個(gè)Employee類如何通過(guò)manager / manages角色與它本身相關(guān)。當(dāng)一個(gè)類關(guān)聯(lián)到它本身時(shí),這并不意味著類的實(shí)例與它本身相關(guān),而是類的一個(gè)實(shí)例與類的另一個(gè)實(shí)例相關(guān)。

          圖 14:一個(gè)反射關(guān)聯(lián)關(guān)系的實(shí)例

          圖 14:一個(gè)反射關(guān)聯(lián)關(guān)系的實(shí)例

           

          圖 14 描繪的關(guān)系說(shuō)明一個(gè)Employee實(shí)例可能是另外一個(gè)Employee實(shí)例的經(jīng)理。然而,因?yàn)椤癿anages”的關(guān)系角色有 0..*的多重性描述;一個(gè)雇員可能不受任何其他雇員管理。

          可見(jiàn)性
          在面向?qū)ο蟮脑O(shè)計(jì)中,存在屬性及操作可見(jiàn)性的記號(hào)。UML 識(shí)別四種類型的可見(jiàn)性:public,protected,private及package。

          UML 規(guī)范并不要求屬性及操作可見(jiàn)性必須顯示在類圖上,但是它要求為每個(gè)屬性及操作定義可見(jiàn)性。為了在類圖上的顯示可見(jiàn)性,放置可見(jiàn)性標(biāo)志于屬性或操作的名字之前。雖然 UML 指定四種可見(jiàn)性類型,但是實(shí)際的編程語(yǔ)言可能增加額外的可見(jiàn)性,或不支持 UML 定義的可見(jiàn)性。表4顯示了 UML 支持的可見(jiàn)性類型的不同標(biāo)志。

          表 4:UML 支持的可見(jiàn)性類型的標(biāo)志

          標(biāo)志 可見(jiàn)性類型
          + Public
          # Protected
          - Private
          ~ Package

          現(xiàn)在,讓我們看一個(gè)類,以說(shuō)明屬性及操作的可見(jiàn)性類型。在圖 15 中,所有的屬性及操作都是public,除了 updateBalance 操作。updateBalance 操作是protected。

          圖 15:一個(gè) BankAccount 類說(shuō)明它的屬性及操作的可見(jiàn)性

          圖 15:一個(gè) BankAccount 類說(shuō)明它的屬性及操作的可見(jiàn)性

           

          UML 2 補(bǔ)充
          既然我們已經(jīng)覆蓋了基礎(chǔ)和高級(jí)主題,我們將覆蓋一些由UML 1. x增加的類圖的新記號(hào)。

          實(shí)例
          當(dāng)一個(gè)系統(tǒng)結(jié)構(gòu)建模時(shí),顯示例子類實(shí)例有時(shí)候是有用的。為了這種結(jié)構(gòu)建模,UML 2 提供 實(shí)例規(guī)范 元素,它顯示在系統(tǒng)中使用例子(或現(xiàn)實(shí))實(shí)例的值得注意的信息。

          實(shí)例的記號(hào)和類一樣,但是取代頂端區(qū)域中僅有的類名,它的名字是經(jīng)過(guò)拼接的:

          Instance Name : Class Name

          舉例來(lái)說(shuō):

          Donald : Person

          因?yàn)轱@示實(shí)例的目的是顯示值得注意的或相關(guān)的信息,沒(méi)必要在你的模型中包含整個(gè)實(shí)體屬性及操作。相反地,僅僅顯示感興趣的屬性及其值是完全恰當(dāng)?shù)摹H鐖D16所描述。

          圖 16:Plane類的一個(gè)實(shí)例例子(只顯示感興趣的屬性值)

          圖 16:Plane類的一個(gè)實(shí)例例子(只顯示感興趣的屬性值)

           

          然而,僅僅表現(xiàn)一些實(shí)例而沒(méi)有它們的關(guān)系不太實(shí)用;因此,UML 2 也允許在實(shí)體層的關(guān)系/關(guān)聯(lián)建模。繪制關(guān)聯(lián)與一般的類關(guān)系的規(guī)則一樣,除了在建模關(guān)聯(lián)時(shí)有一個(gè)附加的要求。附加的限制是,關(guān)聯(lián)關(guān)系必須與類圖的關(guān)系相一致,而且關(guān)聯(lián)的角色名字也必須與類圖相一致。它的一個(gè)例子顯示于圖 17 中。在這個(gè)例子中,實(shí)例是圖 6 中類圖的例子實(shí)例。

          圖 17:圖 6 中用實(shí)例代替類的例子

          圖 17:圖 6 中用實(shí)例代替類的例子

           

          圖 17 有Flight類的二個(gè)實(shí)例,因?yàn)轭悎D指出了在Plane類和Flight類之間的關(guān)系是 0或多。因此,我們的例子給出了兩個(gè)與NX0337 Plane實(shí)例相關(guān)的Flight實(shí)例。

          角色
          建模類的實(shí)例有時(shí)比期望的更為詳細(xì)。有時(shí),你可能僅僅想要在一個(gè)較多的一般層次做類關(guān)系的模型。在這種情況下,你應(yīng)該使用 角色 記號(hào)。角色記號(hào)類似于實(shí)例記號(hào)。為了建立類的角色模型,你畫一個(gè)方格,并在內(nèi)部放置類的角色名及類名,作為實(shí)體記號(hào),但是在這情況你不能加下劃線。圖 18 顯示一個(gè)由圖 14 中圖描述的雇員類扮演的角色實(shí)例。在圖 18 中,我們可以認(rèn)為,即使雇員類與它本身相關(guān),關(guān)系確實(shí)是關(guān)于雇員之間扮演經(jīng)理及團(tuán)隊(duì)成員的角色。

          圖 18:一個(gè)類圖顯示圖14中扮演不同角色的類

          圖 18:一個(gè)類圖顯示圖14中扮演不同角色的類

          注意,你不能在純粹類圖中做類角色的建模,即使圖 18顯示你可以這么做。為了使用角色記號(hào),你將會(huì)需要使用下面討論的內(nèi)部結(jié)構(gòu)記號(hào)。

          內(nèi)部的結(jié)構(gòu)
          UML 2 結(jié)構(gòu)圖的更有用的功能之一是新的內(nèi)部結(jié)構(gòu)記號(hào)。它允許你顯示一個(gè)類或另外的一個(gè)分類器如何在內(nèi)部構(gòu)成。這在 UML 1. x 中是不可能的,因?yàn)橛浱?hào)限制你只能顯示一個(gè)類所擁有的聚合關(guān)系。現(xiàn)在,在 UML 2 中,內(nèi)部的結(jié)構(gòu)記號(hào)讓你更清楚地顯示類的各個(gè)部分如何保持關(guān)系。

          讓我們看一個(gè)實(shí)例。在圖 18 中我們有一個(gè)類圖以表現(xiàn)一個(gè)Plane類如何由四個(gè)引擎和兩個(gè)控制軟件對(duì)象組成。從這個(gè)圖中省略的東西是顯示關(guān)于飛機(jī)部件如何被裝配的一些信息。從圖 18 的圖,你無(wú)法說(shuō)明,是每個(gè)控制軟件對(duì)象控制兩個(gè)引擎,還是一個(gè)控制軟件對(duì)象控制三個(gè)引擎,而另一個(gè)控制一個(gè)引擎。

          圖 19: 只顯示對(duì)象之間關(guān)系的類圖

          圖 19: 只顯示對(duì)象之間關(guān)系的類圖

           

          繪制類的內(nèi)在結(jié)構(gòu)將會(huì)改善這種狀態(tài)。開(kāi)始時(shí),你通過(guò)用二個(gè)區(qū)域畫一個(gè)方格。最頂端的區(qū)域包含類名字,而較低的區(qū)域包含類的內(nèi)部結(jié)構(gòu),顯示在它們父類中承擔(dān)不同角色的部分類,角色中的每個(gè)部分類也關(guān)系到其它類。圖 19 顯示了Plane類的內(nèi)部結(jié)構(gòu);注意內(nèi)部結(jié)構(gòu)如何澄清混亂性。

          圖 20:Plane類的內(nèi)部結(jié)構(gòu)例子。

          圖 20:Plane類的內(nèi)部結(jié)構(gòu)例子。

           

          在圖 20 中Plane有兩個(gè) ControlSoftware 對(duì)象,而且每個(gè)控制二個(gè)引擎。在圖左邊上的 ControlSoftware(control1)控制引擎 1 和 2 。在圖右邊的 ControlSoftware(control2)控制引擎 3 和 4 。

          結(jié)論
          至少存在兩個(gè)了解類圖的重要理由。第一個(gè)是它顯示系統(tǒng)分類器的靜態(tài)結(jié)構(gòu);第二個(gè)理由是圖為UML描述的其他結(jié)構(gòu)圖提供了基本記號(hào)。開(kāi)發(fā)者將會(huì)認(rèn)為類圖是為他們特別建立的;但是其他的團(tuán)隊(duì)成員將發(fā)現(xiàn)它們也是有用的。業(yè)務(wù)分析師可以用類圖,為系統(tǒng)的業(yè)務(wù)遠(yuǎn)景建模。正如我們將會(huì)在本系列關(guān)于 UML 基礎(chǔ)的文章中見(jiàn)到的,其他的圖 -- 包括活動(dòng)圖,序列圖和狀態(tài)圖——參考類圖中的類建模和文檔化。

          關(guān)于“UML 基礎(chǔ)”的本系列的后面的元件圖。

          腳注
          1 delayFlight沒(méi)有返回值,因?yàn)槲易鞒隽嗽O(shè)計(jì)決定,不要返回值。有一點(diǎn)可以爭(zhēng)論的是,延遲操作應(yīng)該返回新的到達(dá)時(shí)間,而且,如果是這種情形,操作屬性將顯示為 delayFlight(numberOfMinutes : Minutes) : Date。

          2可能看起來(lái)很奇怪, BankAccount 類不知道 OverdrawnAccountsReport 類。這個(gè)建模使報(bào)表類可以知道它們報(bào)告的業(yè)務(wù)類,但是業(yè)務(wù)類不知道它們正在被報(bào)告。這解開(kāi)兩個(gè)對(duì)象的耦合,并因此使系統(tǒng)變得更能適應(yīng)變化。

          3 軟件包對(duì)于組織你的模型類是龐大的,但是記住重要的一點(diǎn)是,你的類圖應(yīng)該是關(guān)于建模系統(tǒng)的容易交流的信息。在你的軟件包有許多類的情況下,最好使用多個(gè)主題類圖,而不是僅僅產(chǎn)生一個(gè)大的類圖。

          4 要理解重要一點(diǎn),當(dāng)我說(shuō)“所有的那些成員”時(shí),我僅僅意味著在當(dāng)前圖中的類將顯示出來(lái)。顯示一個(gè)有內(nèi)容的軟件包的圖,不需要顯示它的所有內(nèi)容。它可以依照一些準(zhǔn)則,顯示包含元素的子集,這個(gè)準(zhǔn)則就是并非所有的軟件包分類器都是必需的。

          5 當(dāng)畫一個(gè)類圖時(shí),在 UML 規(guī)范中,全部要做的只是把類放入長(zhǎng)方形的頂部區(qū)域,而你同理處理接口;然而,UML 規(guī)范認(rèn)為,在這個(gè)區(qū)域放置“class”文本是可選的,如果類沒(méi)有顯示,那么它應(yīng)該被假設(shè)。

          參考資料

          • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文

           

          關(guān)于作者
          Author photoDonald Bell是IBM全球服務(wù)的一個(gè)IT專家,在那兒他和IBM的客戶一起致力于設(shè)計(jì)和開(kāi)發(fā)基于軟件解決方案的J2EE。

           

           

          版權(quán)所有:UML軟件工程組織

          posted on 2006-03-11 22:17 西部村里人 閱讀(701) 評(píng)論(0)  編輯  收藏 所屬分類: Hibernate

          主站蜘蛛池模板: 嵊州市| 景泰县| 新营市| 东乡县| 云阳县| 泌阳县| 沁水县| 齐河县| 甘德县| 常山县| 兴宁市| 万源市| 陕西省| 江油市| 古浪县| 桂平市| 新密市| 来安县| 梅河口市| 溧阳市| 土默特右旗| 梧州市| 平湖市| 西城区| 额敏县| 武城县| 休宁县| 鲁甸县| 望江县| 永德县| 桦川县| 惠东县| 德令哈市| 永安市| 赞皇县| 象山县| 河源市| 青海省| 车致| 新民市| 潜山县|