UML软件工程组织

為何要使用 UML?
Martin Fowler
當今物件導向開發的世界中,第二條大新聞是什麼?那就是『統一模塑語言』(Unified Modeling Language; UML),其不僅獲得物件管理小組(Object Management Group; OMG)所承認,也將取代 BoochCoadJacobsonOdellRumbaughWirfs-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 用法,同時記得有選擇性並突顯重要的資訊。

 

列表 1. 對於圖解 1 所描述的 Java 介面

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();

   ¡

}

 

 

版权所有:UML软件工程组织