在《Use Case Driven Object Modeling With UML: A Practical Approach》這本小巧的書籍提到了「分析癱瘓」(analysis paralysis)一詞,顧名思義,原著作者提醒我們別陷入了過度分析的困境。我推想分析癱瘓可能是這本書的重點論述之一,所以拿它來當作本文的名稱。

本書提出了一個從使用案例(use case)到程式碼(code)的開發方法,稱之為「ICONIX方法」。當然,整本書的重點在論述ICONIX方法的開發程序,不過會令我眼睛一亮的倒不是這個開發方法,說實在的,像這類的OOAD開發方法有太多了,我自己在2007年底出版的《寫給SA的UML/MDA實務手冊》,也是一種OOAD開發方法。

不過,這本小書令我感興趣而想要選讀的原因在於,原著作者提到了十五條「分析癱瘓警訊」(analysis paralysis alerts),對於像我這種重度分析症者,這十五條警訊無疑是最佳的自我警惕指標。另外,原著作者還針對七個主題,提出了「Top 10清單」(Top 10 Lists),這也是經驗智慧的結晶啊!而上述兩者,才是我會打開這本書尋寶的重點。

這本書每一章的篇幅都很少:第一章談ICONIX方法、第二章到第五章分別談到ICONIX方法的必要開發步驟、第六章的通訊圖(Communication Diagram)與狀態圖(State machine Diagram)是選擇性步驟、最後的第七章談需求、第八章談實作,就這樣,沒了,點到為止,簡單俐落。由於,分析癱瘓警訊和Top 10清單散落在各章節中,所以我打算整本書的八個章節都來讀一讀,不跳讀章節,但是每章還是會挑重點來談。

ICONIX方法
比起如RUP(Rational Unified Process)這類知名又龐大的OOAD開發方法,ICONIX方法其實平易近人多了,不僅簡單樸實,更去除了冗長繁雜的步驟,從找出使用案例到實作出程式碼,一共只需要五個主要步驟。

領域建模
領域建模主要在找出問題領域(problem domain)中,重要的具體事物以及抽象概念,為它們建立相對應的物件(object),並以UML類別圖(class diagram)來呈現之。

分析癱瘓警訊
原著作者提出了十五條分析癱瘓警訊,此處我們先討論了前三條跟領域模式有關的警訊。

Top 10領域建模錯誤
原著作者列出了十項領域建模錯誤(domain modeling errors),可是卻沒有多加說明,所幸這十項錯誤都很容易理解,我們一塊來看看。

書籍簡介
Use Case Driven Object Modeling With UML: A Practical Approach

作者:Doug Rosenberg and Kendall Scott

頁數:200頁

出版社:Addison-Wesley Professional

出版時間:1999 MarchICONIX方法

比起如RUP(Rational Unified Process)這類知名又龐大的OOAD開發方法,ICONIX方法其實平易近人多了,不僅簡單樸實,更去除了冗長繁雜的步驟,從找出使用案例到實作出程式碼,一共只需要五個主要步驟,如下圖所示。 小時候玩紙上迷宮時,最快找到路徑的方法是從出口倒推,這樣通常會可以省略走入枝節的時間,很快就可以找出唯一的路徑了。所以,我們倒推著來談ICONIX方法的五個主要步驟,你可以發現這恐怕是最簡潔的開發路徑了,如下列:

.第5步驟、程式碼
ICONIX方法最後一個步驟就是編寫出程式碼,而編寫程式碼所需的最關鍵資訊是,類別的屬性(attributes)、方法(methods)以及類別之間的關係。

.第4步驟、循序圖
針對每一個使用案例思考及建構循序圖(sequence diagram)的過程,其實也就是在分派責任給物件,同時也就是在決定類別的方法。

.第3步驟、穩健圖
在繪製循序圖之前,需要先透過穩健圖(robustness diagram)決定有哪些物件將參與使用案例。

.第2步驟、使用案例模式(圖與敘述)
在繪製穩健圖之前,需要描述一群物件合作的原由,所以此時將需要撰寫使用案例敘述(use case narrative)。

.第1步驟、類別圖
撰寫使用案例敘述之前,需要先對領域概念有初步的認識,這樣才能寫出貼切的使用案例敘述,因此需要建構類別圖(class diagram)。 接下來的各小節中,我們會依序來說明這五大步驟,以及相關的分析癱瘓警訊與Top 10清單。這五大步驟中,除了穩健分析是Ivar Jacobson先生所提出且未併入UML2外,其餘的類別圖、使用案例圖、循序圖、通訊圖和狀態圖都屬於UML2的十三款圖之內。所以,針對穩健分析的部分,我們會多補充一些相關的知識。領域建模

領域建模主要在找出問題領域(problem domain)中,重要的具體事物以及抽象概念,為它們建立相對應的物件(object),並以UML類別圖(class diagram)來呈現之。

撰寫使用案例敘述之前,需要先對領域概念有初步的認識,這樣才能寫出貼切的使用案例敘述,因此建構類別圖即為ICONIX方法的首要步驟。ICONIX方法主張領域建模在先,第二步驟才開始建構使用案例圖並撰寫使用案例敘述。領域建模在ICONIX方法中的位置,在圖1左下方。

倒底是先找出領域物件,才利用這些領域物件撰寫使用案例敘述,還是先撰寫使用案例敘述,並從使用案例敘述中找出領域物件呢?這在實務上一直是雞生蛋、蛋生雞的問題。實務上,這兩種方法都有人支持,也都沒有標準做法或定論,畢竟管牠是黑貓還是白貓,能抓到耗子最重要。

哪些具體事物以及抽象概念,是重要的且需要為它們建立相對應的物件呢?相信這是許多初學者心中最大的疑惑。一般而言,需要保存在資訊系統中的資料,其所涉及到的具體事物以及抽象概念,通常我們就會為它們建立相對應的物件。

原著書上建議從下列三項文件,做為發現類別、尋找物件的來源,文件內容中的專業名詞可能為類別或屬性(attribute)、動詞可能為操作(operation)或結合關係(association relationship):

˙高階的問題說明文件
˙低階的需求說明文件
˙問題領域內的專家知識

老實說,我沒有參與國外專案的經驗,所以不清楚美國的開發團隊是否真的會撰寫這類的文件。不過,以我參與臺海兩岸的專案經驗來說,我們的開發團隊鮮少撰寫這樣的文件,關於問題領域的描述通常只是三兩句話就打發帶過,要從中挖掘出有用類別、屬性、操作或結合關係,實在很難耶。分析癱瘓警訊

原著作者提出了十五條分析癱瘓警訊,此處我們先討論了前三條跟領域模式有關的警訊。

分析癱瘓警訊1
別讓文法檢驗把你絆住了。(Don’t get bogged down in grammatical inspection.)

原著在這邊提到了第一項分析癱瘓警訊,千萬別陷在這些文件內容去分析名詞、動詞太久,頂多就是花幾個鐘頭,適可而止。前面有提到過,分析文件內容可以做為發現類別、尋找物件的來源,文件內容中的專業名詞可能為類別或屬性、動詞可能為操作或結合關係。我想,如果是臺灣專案的話,說實在的,大概也沒太多文件可以讓我們花時間在這上頭吧!

不過,這一條分析癱瘓警訊倒是讓我想到另一種被UML文法檢驗絆住的情況。這通常發生在初次採用UML的專案,專案成員通常是邊學UML邊進行專案,因此經常會過於擔心UML文法的正確性,拖垮了整個分析流程的進度。也不是說UML文法的正確性不重要,而是要適可而止。就像初學英文一樣,如果太重視英文文法的正確與否,通常會因為怕犯錯而不敢開口說英文。

分析癱瘓警訊2
別太早處理個體數目。(Don’t address multiplicity too early in the project.)

一個物件可以連結多少個另一種物件,其數目限制就是「個體數目」(multiplicity)。個體數目通常會標示在結合關係的兩端點上,如圖2所示。下限最小為零,上限最大為無限大,並以星號(*)代表無限大。如果,僅出現一個數目,代表上下限數目相同。

在下圖的範例中,一個信用卡物件最少可以沒有連結到任何刷卡消費物件,最多則可以連接到無限多個刷卡消費物件。至於,一個刷卡消費物件不僅只能,而且是一定要,連結到一個信用卡物件。



在建構類別圖時,第一步會先找出類別,而且是不含屬性及操作的類別,接下來的動作就不一定了,可能會先定義出屬性,也可能會先定義出操作,或者先定義出結合關係。如果硬是要說個先後順序的話,我通常會建議下列順序:

1.找出類別(不含屬性及操作)
2.建立類別之間的結合關係(不含個體數目)
3.定出操作
4.找出屬性
5.定出個體數目

這樣的順序看起來好像沒什麼,但其實是有理由的。這樣的開發順序成本較低,因為它不會一下子就陷入細究某一個類別,而是針對整體進行多次的循環,每一個循環著重某一個特徵。一旦類別有誤、或者需要切割成數個類別、或是需要跟其他類別合併時,可以立即調整類別圖,不會因為一開始就細究了類別或個體數目,而白白浪費了這段探究細節的時間,或者造成分析癱瘓。

分析癱瘓警訊3
直到細部設計階段,再來擔心聚合關係與組合關係。(Don’t worry about aggregation and composition until detailed design.)

簡單地說,聚合關係和組合關係都是一種「整體」擁有(has)「部分」的關係,前者是以參照方式擁有(has by reference),後者則是以數值方式擁有(has by value)。

比方說,如果我們想要傳達團隊物件是群體,而另一成員物件是它的聚集成員,這樣的整體-部分概念時,就可以採用以參照方式擁有的聚合關係,如下圖所示。


聚合關係圖



但是,如果我們想要傳達剪刀物件是整體,而另一刀柄物件及刀片物件是它的內部組件,這樣的整體-部分狀況時,很適合採用以數值方式擁有的組合關係,如下圖所示。

組合關係圖



由於,聚合和組合關係之間僅有細微的差異,所以許多人搞不清楚如何區辨兩者。原著作者建議可以先用聚合關係來表達整體-部分的擁有關係,直到細部設計階段再來分辨兩者。

我則建議,如果搞不清楚聚合和組合之間的差異,那不如就別理它們了,把它們拋在一旁,別用就是了。特別是UML初學者,很容易畫出有一堆聚合關係和組合關係的類別圖,但這樣的類別圖經常是錯誤的。Top 10領域建模錯誤

原著作者列出了十項領域建模錯誤(domain modeling errors),可是卻沒有多加說明,所幸這十項錯誤都很容易理解,我們一塊來看看。

Top 10領域建模錯誤10
立即指派個體數目,並且確認每一個結合關係都有明確的個體數目。(Start assigning multiplicities to associations right off the bat. Make sure that every association has an explicit multiplicity.)

其實,這一項錯誤跟前面提到的分析癱瘓警訊2(別太早處理個體數目)的概念相同。總之,分析時把握一項大原則——愈是變動性高的細節愈晚分析,或者愈是依賴其他資訊才能決定的事項也愈晚分析。

Top 10領域建模錯誤9
做詳盡的名詞及動詞分析。(Do noun and verb analysis so exhaustive that you pass out along the way.)

同樣地,這一項錯誤跟前面提到的分析癱瘓警訊1(別讓文法檢驗把你絆住了)的概念相同。雖然,高階的問題說明文件、低階的需求說明文件、問題領域內的專家知識等等相關文件,可以做為尋找類別、屬性、操作及關係的資料來源,但切勿分析過頭,因而導致分析流程的癱瘓。

Top 10領域建模錯誤8
未探究使用案例與循序圖,就逕自指派操作給類別。(Assign operations to classes without exploring use cases and sequence diagrams.)

如果,在未建構使用案例與循序圖之前,就直接指派操作給類別,是錯誤的。也就是說,先建構使用案例圖、編寫使用案例敘述以及建立循序圖之後,從中獲取相關資訊,因此才能夠指派操作給類別。

步驟順序如下:

1.建構使用案例圖
2.編寫使用案例敘述
3.建立循序圖
4.定出操作

還記得我們在分析癱瘓警訊2處,提到了分析步驟為:

1.找出類別(不含屬性及操作)
2.建立類別之間的結合關係(不含個體數目)
3.定出操作
4.找出屬性
5.定出個體數目

合併兩者之後,可以得到下述的分析步驟:

1.建構使用案例圖
2.編寫使用案例敘述
3.找出類別(不含屬性及操作)
4.建立類別之間的結合關係(不含個體數目)
5.建立循序圖
6.定出操作
7.找出屬性
8.定出個體數目

Top 10領域建模錯誤7
在還未確認滿足使用者需求之前,便逕自為了重用性而優化程式碼。(Optimize your code for reusability before making sure you’ve satisfied the user’s requirements.)

我認為這項錯誤提到下述兩個重點:

1.滿足使用者需求,一定是最優先的事情。即便是「重用」(reuse)這麼重要的事情,其優先程度也無法超越使用者需求,否則就本末倒置了。

2.高品質的程式碼才有重用的價值,所以日後想要重用現在的程式碼,必先進行程式碼的優化行動。因此,可以分為兩階段目標來編寫程式碼,第一階段的編碼目標是滿足使用者需求,第二階段的編碼目標則是優化程式碼,以便日後的重用。

Top 10領域建模錯誤6
針對每一個具有整體-部分特色的結合關係,爭論該採用聚合或是組合。(Debate whether to use aggregation or composition for each of your part-of associations.)

這一項錯誤又跟前面提到的分析癱瘓警訊3(直到細部設計階段,再來擔心聚合關係與組合關係)的概念相同。別把時間浪費在爭論聚合或組合上頭,如果真的搞不清楚,當下也沒有資深的UML研究員可以詢問的話,那不如就別用這些概念了。

Top 10領域建模錯誤5
在還沒有建立問題空間的模式之前,就逕自假定了具體的實作策略。(Presume a specific implementation strategy without modeling the problem space.)

美國著名的哲學及教育大師杜威(John Dewey)曾說過:「清楚說明問題就已經把問題解決了一半。」也就是說,我們在提出明確具體的實作策略(解決方案)之前,可以先透過建立問題領域模式來清楚說明問題。

Top 10領域建模錯誤4
寧可採用難以理解的字詞做為類別名稱,譬如cPortMgrIntf,而不用淺而易懂的字詞,如PortfolioManager。(Use hard-to-understand names for your classes—like cPortMgrIntf—instead of intuitively obvious ones, such as PortfolioManager.)

《The Elements of UML 2.0 Style》一書的原著作者也說過,最好採用一般性且完整的單數名詞做為類別名稱,比方說「顧客」類別,就用完整的單數名詞“customer”,不要用縮寫“cust”,也不要用複數“customers”。原因在於,便於理解與溝通。

Top 10領域建模錯誤3
在領域模式中,直接採用實作層面的概念,像是朋友關係和參數化類別。(Jump directly to implementation constructs such as friend relationships and parameterized classes.)

既然我們現在是在建構領域模式,就不能在此模式中出現實作平台或程式語言特有的概念,像是朋友關係(friend relationship)或參數化類別(parameterized class)等等。這些概念都不是領域概念,而是實作層面的概念。

Top 10領域建模錯誤2
在領域類別與關聯式資料庫表格之間,建立一對一對映的關係。(Create a one-for-one mapping between domain classes and relational database tables.)

如果是全新的系統,我通常會建議參考類別圖來建立關聯式資料庫的表格。一般而言,類別圖與關聯式資料庫的表格不會是單純的一對一對映的情況,至少在類別屬性與表格欄位上頭就不盡相同了。

倘若已經存在舊有系統,關聯式資料庫的表格設計是很好的資料來源,對於我們建立類別圖有很大的幫助。不過,也不會是一個表格對映一個領域類別這麼單純,通常還是需要經過一番分析,才能夠獲得正確的類別圖。

Top 10領域建模錯誤1
太早採用樣式,因而導致建構出來的模式與使用者問題的關聯性不大。(Perform “premature patternization”, which involves building cool solutions, from patterns, that have little or no connection to user problems.) 我不反對在領域類別圖中使用樣式(pattern),像我這些年來就經常在專案中使用Peter Coad的交易樣式(transaction patterns),也將交易樣式的概念介紹給很多學員,不過,除了交易樣式之外,我幾乎沒有在領域類別圖中使用過其他的樣式,原因就是怕得到的類別圖背離了領域空間。

熱門新聞

Advertisement