當今物件導向開發的世界中,第二條大新聞是什麼?那就是『統一模塑語言』(Unified
Modeling Language; UML),其不僅獲得物件管理小組(Object
Management Group; OMG)所承認,也將取代
Booch、Coad、Jacobson、Odell、Rumbaugh、Wirfs-Brock
等分析及設計方法原先所使用的表示法,成為全新唯一的表示法。此舉將終結軟體開發人員究竟要使用那些方法,這類令人生厭的爭議,我們將進入和睦、友愛及提升生產力的新時期(就算那些舊架構的方法已經相當成熟了,卻從未達到這樣的水準,
對此也只能一笑置之)。
假如你是 B.S.
(before standardization;
標準化之前)方法之一的方法迷(keen
user),你鑽研(bite
the bullet)、轉換至 UML
時,不免暗地抱怨,沒有看到你所喜愛方法中的
x 特性,而你所不喜歡的
y 及
z 特性卻充塞其中。但是,你是否真的冷靜下來,思考像
UML 這樣的塑模表示法,為何是有用的嗎?
詢問一位方法論大師(methodologist;
在我們業界指的是創造方法論的人)有關這方面的看法時,會招致一頓軟體品質如何如何的嚴厲訓斥。方法論大師會談論到,我們的產業遭受到怎樣的危機,缺乏軟體品質所遭致的問題,良好設計的重要性
... 等等。這樣也好(雖然我想軟體產業在最近幾十年已經做得很好了),但是如何確實地實施
UML 才是有幫助的?詢問
CASE 工具廠商時,你將會上一堂課,是有關改善品質、文件自動化及程式碼產生器的生產值,然而我們大家都知道,CASE
工具廠商接下來的動作會是什麼。
假如你是一位開發人員,質疑所有方法的本質,不過是另類的管理流行時尚,你一想起會產生毫無用處的紙張,就感到戰慄,然後
UML 恰好佯裝成關懷這類問題,而成為另一種表示法(notation),至少這是目前僅有的。可是,你也瞭解下次你必須更改系統時,在你必須修護程式碼往後的幾個版本,這些
UML 圖還是有所助益的。
我早在軟體職業生涯中學會方法,既使我具有工程的背景,然而這些方法似乎成為一種天然的知識領域,這般的吸引著我。大多數的工程科系採用繪圖來描述如何建構事物,同時相當用心的
,根據這份設計圖來做這些事物,我明白方法論的圖型也具相同功效。有段時間,我學習類似的方式(the
lie of that analogy),然而我仍舊發現這些方法是有用的,儘管我對於某些開發人員不喜歡這些方法深表同情。
接著下來我要說明為何我發現
UML 是有用的,首先我快速的提醒各位,
UML 『是一種塑模語言,而非方法(或方法論)』,同時以此作為下面論述的開始。UML
訂定了一些圖型,以及這些圖型的意涵。而方法則更進一步描述開發軟體的步驟,什麼樣的圖型在什麼順序中產生,由誰來做那些工作
... 等。支持
UML 的方法是各自獨立的,過了明年或明後年,我們將看到不同人士提供各種運用
UML 表示法的方法。然而,你不須要使用方法,才會利用
UML,在這篇文章裡,我不去假定任何特定的開發方法。
因此,如果我們除去所有方法的裝飾,除了少數你能夠繪製的圖型樣式外,被留下來的還有什麼?這個問題,從「UML
有什麼用途?」變成了「這些圖型有什麼用?」
答案可以歸結成一詞:『溝通』(譯註:英文是一字:communication),這是一個重要的詞彙,軟體如此地迷惘
,以致於難以開發的原因,主要就在於溝通。我們知道,假若我們只要在週末偷閒一下,而程式碼就此消失,事情將是如何簡單,困難的癥結在於我們必須與多位開發人員溝通。UML
之所以重要,就是因為它有助於軟體開發人員之間的溝通。我們必須在某種程度上使用它,以協助溝通,而非阻礙溝通。
圖解 1
說明了 UML
如何協助溝通的範例,此圖型一開始是用來描述
Java 抽象視窗工具集(Java's
Abstract Windowing Toolkit; AWT)的容器類別(Container
class),透過閱讀這個圖型,我能夠了解一大堆東西。我能夠瞭解容器(Container)是元件(Component)的子型態(subtype),可以把元件製作成可視的(visible)或主動的(active),以及其他類型的元件,這些元件包括標籤(labels)、按鈕(buttons)以及其他種種。我可以詢問一個容器有關它所包容的元件,但是並非所有的元件都需要容器。容器(Containers)包含元件(Components),容器(Containers)也可能包含其他容器(Containers),同時容器擁有一個佈置管理者(layout
manager)。容器就如同元件般,屬於抽象類別(abstract
class),其子型態包含畫板(panels)及視窗(windows)。視窗能夠顯示及處置視窗本身,視窗也有框架(frame)及對話方塊(dialog)兩種子類別(subclasses),兩者皆有標題列,同時能夠設定其大小是否可以變更(resize)。雖然視窗的兩種子類別都可以做上述的事,然而這些行為並非視窗本身的一部分。可以將對話方塊(Dialogs)標示為模組式(modal),然而框架(frames)卻不可以。
你可能喜歡這個圖型,也有可能喜歡我前面那段論述,這端賴你是否熟悉
UML,以及你是喜歡視覺化的敘述,或者喜歡敘事式的陳述。關於此,我喜歡視覺化,然而有些人喜歡文字方式,即使他們也懂得這些圖型。你可以給他們文字描述,或者(或許會更好)給他們一段程式碼選集(如列表
1
所示)。那一個是你願意選擇的?那一個是你的同僚所想要的?這些問題對於
UML 及類似語言的角色是至關緊要的。我發現有些人喜歡文字的方式,有些人喜歡圖型的方式,還有某些人在某些事物上選擇圖型,同時在某些事物上選擇文字。最後,圖型僅有在可以強化溝通的情況下才值得去做。
除了注意那些圖型展示甚麼之外,你也該注意到那些圖型不能夠展示甚麼,類別整體描述有較圖解
1 或列表
1
所標示的介面更大。我未曾提到佈置管理者(Layout
Manager)是一個介面,或者那個元件實作若干介面,許多人可能會因此而責難圖解
1 不夠完整。它是不完整,但不完整是一種缺點嗎?在圖型裡,我決定去描寫那些類別的特性,並且慎重的決定那些不該顯示出來。事實上,我所顯示出來的某些特性,就是我所要突顯出來的特性。
選擇所要強調的資訊,是溝通很重要的一環。在類別的任一群體中,為了取得這些類別最初的理解,去了解某些觀點(aspects)是相當重要的。假如你展示每件事,你會失去引出那些特點,同時你的讀者會對於首要了解的事物,以及往後才須專注的細枝末節毫無概念。當我使用類別圖,我是為了最初的理解而利用它們,以便於瞭解我想表達這些類別的關鍵觀點。我知道讀者經常是從
Javadoc 檔案中,去取得這些介面完整的敘述。
我鼓勵你以這種有選擇性的方式來使用類別圖,這樣做不僅可以促進圖型溝通的價值,也可以使它們容易維護(keep
up to date)。你無須為了類別每一個小改變就變更圖型,既然難以維護這些各式各樣的圖型,為重大的問題之一,這種做法就有相當大的好處。
就像鼓勵有選擇性一般,我也鼓勵人們去強調介面(interface)而非實作。我在元件上顯示一個
isEnabled 的屬性(attribute),這不是說元件類別有一個資料欄位(field)稱為
isEnabled (我真的沒有注意到,因為它無關緊要)。其所表達的意思是你可以假設這個類別有這樣的屬性,然而你要從類別外部透過適當的操作(operations)來存取內部的資料。理論下,可能有這些操作的命名約定(在
Java 程式庫的這些日子,命名的方式為
isBooleanAttribute
及 setBooleanAttribute)。我不顯示類別的操作,因為我發現屬性的表示方式
,更能適當地傳達程式碼的意圖。屬性也可延伸至結合關係(associations),我不知道容器(Container)及元件(Component)之間存在那些資料結構,這些操作會使人聯想到這些結合關係。
許多人士以實作的觀點來繪製類別圖,即是將屬性(attributes)及結合關係(associations)反映至資料結構中,這些資料結構之所以有用,乃在於你期望表達甚麼。無論如何,通常
這些介面那些是最重要的。你該決定甚麼是你所根據的觀點,甚麼是你想要表達的。
當討論到某一件設計,還有你可能如何去變更它時,我發現圖型也是有用的。
假如你擁有一群設計師正致力於一項設計,嘗試在白板上繪製設計的草圖,描繪幾個替代方案。我發現我們在探討有關事物時,視覺化是很有效的辦法。(CRC
卡是另外一種有效的技術。)
這項技術有一點特別重要的變化,是發生在當我正與領域專家合作,嘗試去了解我們所要建構的系統時。在這種情況下,我使用最少的表示法,並且聚精會神於領域專家腦中所描述的概念,而不是思考任何特定的軟體情況。我發現教導這種概念上的塑模風格,對於沒有軟體背景的人士是相當容易的。
接下來,使用這些圖型,
我們能夠共同地發展出一套定義正確的字彙,用於討論領域相關事項,同時能夠提出對於討論及目的軟體皆有益的抽象概念,當我從事於如保健及金融貿易這類複雜的領域時,這對我而言是一大恩惠。
統一規格在此是有用的,乃因其可加強溝通的品質,當他們使用各種圖型式樣(diagramming
styles)與人溝通時,這種思想交流是困難的。擁有一個單一的標準,我們可以確認,假使人們懂得少許圖型式樣的話,他們一定懂得標準化的圖型。但是不要走過頭了,UML
包含許多表示法,並且沒有規定說你全部都必須用到。嘗試著運用這些表示法中適當地、少量的部分,不要使用進階的概念,除非它們確有必要。雖然你應該盡你所能去忠於標準,然我必須承認,如果需要的話,我並不害怕去篡改表示法。我不這樣做的原因,通常是每次篡改表示法就需要對此作說明,同時不是讀者所熟悉的,但是若這麼做能加強溝通,我就去做它。
所以,如果你是
UML
的新手,根據你所需傳達的想法去嘗試使用它,實驗可以了解那些可以做,以及那些不可以做。
透過實作去學習表示法,並且逐步地學習它。如果你對塑模表示法相當有經驗,促使自己去熟悉
UML,對你來說該不成問題,但是要當心理解過頭了。謹記其主要的目的,注意到如何讓你的圖型能良好地溝通,不要貿然使用較之你的讀者
能力上所能處理,更加以難懂的 UML
用法,同時記得有選擇性並突顯重要的資訊。
public abstract class Component {
public Container getParent();
public boolean isEnabled();
public boolean isVisible();
public void setEnabled (boolean b);
public void setVisible (boolean b);
...
}
public class Button extends Component {...}
public class Label extends Component {...}
// other component subclasses
public abstract class Container extends Component {
public Component add (Component comp);
public void remove (Component comp);
public Component[] getComponents();
public LayoutManager get Layout();
public void setLayout(LayoutManager mgr);
...
}
public class Panel extends Container {...}
public class Window extends Container {
public void show();
public void dispose();
...
}
public class Frame extends Window {
public String getTitle();
public void setTitle(String title);
public boolean isResizable();
public void setResizable (boolean b);
...
}
public class Dialog extends Window {
public String getTitle();
public void setTitle(String title);
public boolean isResizable();
public void setResizable (boolean b);
public boolean isModal();
public void setModal();
¡
}
|
|