雖然,在前面的系列文章中,我們從沒正式談過類別(Class)的概念,但是已經看過好幾次它的蹤影了。在關於UML母模的圖中,看到的矩形圖示,就是類別。一個類別(Class)代表一群相同的物件(Object)。這群物件在下列特性上頭,呈現出相同並且可以讓人辨識出相同,這些特性有:

1.語意(sematic):概念、定義。其實,就是指同樣的東西,我們會說同樣的定義、同樣的概念、同樣的語意、同樣一種東西。

2.屬性(attribute):資料。這一群物件具有相同的屬性特質、或者說相同的資料項目,但是每個物件可以保有自己的屬性「值」(Value)。

3.操作(operation):行為。這一群相同概念、相同屬性的物件,也具有相同的行為、動作,這些行為或動作我們會將它們分解並設計成一個個不同的操作。這一群物件,可以享有並執行這一組相同的操作。當然,在不同的時刻、不同的流程、不同的互動、不同的目的、不同的情境下,這一群物件可能執行不同的操作。

4.關係(relationship):結合關係、組合關係、聚合關係。同類的一群物件,除了享有相同的語意、屬性和操作外,最容易被人遺漏的是,它們也享有相同的關係。

在真實世界中、在問題領域中,我們可以發現許多種類的物件。無論是,感官可以感覺到的「實體物件」(physical objects);或者是,感官無法感覺到、但是我們的腦袋確實可以認知並辨識的「非實體物件」(nonphysical objects)。這些真實的物件都可能會被我們抽象化,並且實作成系統內部的軟體物件。

延續一開始說的四個相同特性,因此我們可以推想,在類別的矩形圖示中,應該會記錄著這些特性吧?確實如此,請你看到的圖1類別圖中,典型的類別圖示包含三個區塊,最上層放置類別名稱(概念),中間層放置一組屬性,最下層放置一組操作。然後,類別的矩形圖示之間可以放置各式的關係。

圖1 類別

緊接著,我們打開類別的性質表來看看,還有哪些特性被收錄進來了,如圖2所示。其中的「樣版」(Template)概念屬於UML高級認證的範圍,我們會留到後面的類別圖的中高級概念小節中,才來詳細說明。

圖2 類別的性質表

還有,類別性質表中的能見度(Visibility)、抽象(Is Abstract)、葉節點(Is Leaf)這三個特性,我們用例圖的章節中已經談過,這邊就不重複了。不過,我們可以簡單看一下UML母模,如圖3所示。類別因為一路繼承了可被重新定義的元素(RedefinableElement)和類詞(Classifier),所以也就因此繼承了葉節點和抽象特性了。有沒有覺得這張圖很眼熟,想起來了嗎?我們在用例圖的章節中,談到「產出物」(Artifact)時,同樣看到產出物繼承了可被重新定義的元素,以及繼承了類詞。

圖3 類別[UML母模]

至於,「主動類別」(Active Class)的概念是第一次出現,它的預設值是「否」(False),也就是說,一般的類別都不是主動類別,或者稱為「被動類別」(Passive Class)。簡單地說,主動物件(Active Object)擁有自己的執行緒(Thread),通常用在即時系統(Real-Time System)的同步(Concurrency)設計中,一般商用系統鮮少用主動物件。

圖4 類別[UML母模]

 

 

UML規格書有建議主動類別的圖示可以用雙直線,如圖4所示,這樣就可以一眼辨識出主動類別或者是被動類別了。不過,VS2010/UML沒有支援這樣的圖示,圖4是從StarUML中截取的。

最後,請你打開類別性質表中的模版,數一數,類別一共有八個模版,如圖5所示,條列說明如下:

圖5 類別[UML母模]

 

 

 

● 輔助(auxiliary)和焦點(focus):這兩個要一塊看,而且兩者應該是互斥的。焦點類別通常包含了主要的、基礎的、核心的流程,並且經常搭配多個輔助類別。輔助類別則通常包含次要的邏輯或流程,用來支援焦點類別。

● 實作類別(implementationClass):某種程式語言實作出來的類別。

● 型別(type):型別可以跟實作類別一塊看,型別同樣可以擁有屬性和結合關係,但是型別的操作沒有具體實作。一個物件可能被歸類於某一個實作類別,但是該物件卻可以同時符合(conform)多種不同的型別。

● 母類別(metaclass):一般類別誕生個體(也稱為物件),但是母類別誕生的個體比較特別,它誕生類別。

● 實現(realization)與規格(specification):在用例圖的章節中,我們就已經談過這兩個模版了。它們繼承自類詞的模版,實現代表含有具體實作,然而規格代表則未包含具體實作。

圖6 公用類別

 

 

● 公用(utility):這八個類別模版中,我個人覺得公用類別大概是最實用、也最常用的,可以把一些公共的、共用的、像是工具類的屬性和操作收錄在公用類別中,如圖6所示。屬性

屬性(Attribute)是類別內部非常重要的組成元素之一,它的概念簡單,其實就是用來保存資料罷了。不過,你要是打開屬性的性質表一看,會發現相關的瑣碎性質還真不少,如圖7所示。

圖7 屬性的性質表

圖8 屬性的格式

 

 

 

那我們就一個一個來看吧。但是我發現,無論做了多少設定,VS2010/UML在類別圖示上永遠都出現最一般性的屬性格式,如圖8所示。

屬性名稱後頭放置屬性的資料型別,不過兩者中間會用冒號分隔。UML預設了四個原生型別(Primitive Type),你可以打開屬性性質表的型別(Type)查看一下,會發現有如圖9的設定。

圖9 靜態屬性與靜態操作[StarUML]

 

 

 

布林(Boolean):包含true和false。

● 整數(Integer):包含了正負整數和零。

● 字串(String):字串要用「雙引號」(“”)括起來。

● 無限自然數(UnlimitedNatural):包含正整數和零,並且使用「星號」(*)代表無限大,請參考維基百科說明。

UML也同樣預設了四種能見度,在用例圖時我們提過能見度,當時沒說明能見度的符號。在屬性和操作名稱前頭出現的減號、加號等等符號,就是能見度的符號,條列如下:

● 公開(Public):公開能見度的符號是「加號」(+)。通常,我們不會將屬性的能見度設為公開等級,因為這樣就打破了物件的資訊隱藏的封裝特性了。不過,操作的預設能見度,就會是公開等級,方便外界呼叫使用。

● 私有(Private):私有能見度的符號是「減號」(-)。屬性能見度的預設值是私有等級。少數不想讓外頭呼叫的操作,也會被設成私有等級。

● 保護(Protected):保護能見度的符號是「井號」(#)。通常會配合一般化關係使用,當父類別(superclass)想要讓子類別(subsclass)直接使用時,可以將私有屬性改成保護等級的屬性,方便子類別直接存取。

● 套件(Package):套件能見度的符號是「否定號」(~),配合套件(Package)概念一塊使用。

除此之外,我們將屬性的其餘特性一併條列如下:

● 預設值(Default Value):等號後面放置預設值,例如:-付訂金額:Integer=1000。

● 唯讀(Is Read Only):大括號內放置readOnly的字眼,代表這個屬性是唯讀,例如:-付訂金額:Integer=1000{readOnly}。

圖10 靜態屬性與靜態操作[StarUML]

 

 

● 靜態(Is Static):預設值是「否」,代表這個屬性由個別的物件所擁有。如果設定值是「真」,則代表這個屬性由類別本身所擁有。當然,操作也同樣有這個設定。請看到圖10,靜態屬性和靜態操作名稱底下應該要出現底線,但是VS2010/UML的靜態屬性底下的底線不見了。我在多次嘗試之後發現,如果是中文名稱的靜態屬性,下方的底線會消失,但如果是英文名稱的靜態屬性的話,名稱下方就會出現底線。

圖12 OwnerScope是UML1的用詞[StarUML]

 

 

 

請看到圖11,UML規格書上清楚指出,在靜態特徵的表示法上,必須有底線。所以,我們再打開StarUML來確認一下,請看到圖12,確實靜態屬性是有底線的,VS2010/UML應該是中文名稱的問題。

圖11 isStatic是UML2的用詞[UML規格書]

● 衍生(Is Derived):可以從其他資訊計算得出的屬性,就是衍生屬性。比方說,付訂金額是學費的六分之一,只要知道學費,就可以計算出付訂金額,所以付訂金額就是衍生屬性。衍生屬性名稱前頭應該加上斜線(/),像是:/付訂金額。在VS2010/UML的類別圖示中,所有的屬性設定都不會出現在圖面上,不過只要滑鼠游標移近,就可以看到完整的設定,如圖13所示。

圖13 屬性[UML母模]

圖14 屬性[UML母模]

 

 

有時候,屬性的型別不是一般的資料型別,而是我們自訂的類別。再者,這個屬性的內容值可能不是指向一個物件,而是多個物件、一個物件集合時,就會須要下列的「多值」(multivalue)設定了,如圖14所示。

● 排序(Is Ordered):用來指出這組屬性多值裡頭的物件是否有特殊的排序法,預設值是「否」(false)。

● 唯一(Is Unique):用來指出這組屬性多值裡頭的每個物件是否唯一,預設值是「真」(true)。

● 個體數目(Multiplicity):用來指出這組屬性多值裡有多少個物件,表示法為「下限..上限」。最小下限為零(0),最大上限是無限大(*)。

其實,屬性從好幾個父類別身上,繼承了我們在上述看到的一堆特性。最後,我們簡單來看一下屬性在UML母模中的情況,如圖15所示。

圖15 屬性[UML母模]
公用類別與抽象類別
這邊我要補充說明一下公用類別(utility class)和抽象類別(abstract classs)。在實務上,這兩個概念其實不容易搞錯的,不過由於它們的特性很相似,所以我想要補充說明一下它們的特性,如下:

圖16 公用類別與抽象類別

 

●一般人對抽象類別最主要的印象,多半是抽象類別不能誕生個體(instance)。其實,雖然公用類別不是抽象類別,但是它跟抽象類別一樣,是沒有個體的。請看到圖16,抽象類別的類別名稱是斜體字,公用類別則是在類別名稱上方標示了《utility》字眼。

●抽象類別「不能夠」誕生個體,通常是因為有不完整,像是擁有缺乏完整的實作或規格之類的抽象操作(abstract operation),所以不能夠誕生個體。但是,公用類別是「不需要」誕生個體,因為它的屬性和操作都是靜態的(static),不需要誕生個體,直接呼叫公用類別,便可以使用它的靜態屬性和操作。請看到圖17,抽象操作的也是使用斜體字,公用類別則是擁有靜態屬性和靜態操作,以底線標示出靜態。

圖17 靜態與抽象

●在使用上,抽象類別通常會搭配一般化關係一塊出現,並且由底下的子類別來實作抽象操作。但是,公用類別通常會獨立存在,其他類別不需要跟公用類別建立特別的關係,就可以直接使用它。

●但是,公用類別可以同時具有抽象特性嗎?當然可以。一旦公用類別擁有了抽象操作之後,它其實也就同時是個抽象的公用類別,需要透過一般化關係來讓它的子類別實作抽象操作,如此一來其他類別才能夠使用公用子類別,如圖18所示。

圖18 抽象的公用類別

專欄作者

熱門新聞

Advertisement