物件導向實例– 以DCOM 實踐一個簡單的聊天室

文章推薦指數: 80 %
投票人數:10人

【初步分析模型】之「取得線上使用者清單」循序圖. 【初步分析模型】之「訊息收發」 ... 直到現在為止,我們可以將找到的物件,繪製成以下的類別圖(Class diagram)。

作者:朱子 吳明皓 日期:2002年9月 物件導向實例 – 以DCOM實踐一個簡單的聊天室   初步分析模型 觀察先前所製作的UseCase模型,以及情節的描述中,我們可以試著找出聊天室系統領域內的物件,並將它以下圖來表示: 根據IvarJacobson的方式,找出使用案例模型裡的邊界物件(BoundaryObject)、控制物件(Control Object)及實體物件(EntityObject)。

Ivar起初在《Object-Oriented SoftwareEngineering:AUseCaseDrivenApproach》這本巨擘著作中,談到要建構一個穩定的系統,需要藉由這三種物件的互動來達成。

最早他稱邊界物件為介面物件(Interface Object),然而由於近代物件導向的技術中,介面(Interface)一辭賦予不同的實作意義,於是在UML中,更改成為邊界物件。

這三種物件的分野如下: 實體物件(EntityObject):是應用領域中的核心物件,可以長期保存系統裡的資訊,同時通常具有與應用領域相同的生命週期。

用來處理系統資訊的相關行為,也必須包含在實體物件中。

例如 記錄裝置、訂單 ...等。

邊界物件(BoundaryObject):外界與系統互動必須透過邊界物件,換言之,其作為系統外部的物件,與系統內部物件聯繫的媒介,如視窗的操作介面,ATM(自動櫃台機)的輸入裝置。

控制物件(ControlObject):它可作為實體物件與邊界物件的潤滑劑。

例如某些功能或許必須與數個實體物件聯繫,其行為包含數個實體物件的操作,並且傳回一個結果到邊界物件,此時可以透過控制物件來協調領域裡的活動。

例如交易(transaction)物件。

製作上述圖型時,習慣性的在每個邊界物件與實體物件之間,加入一個控制物件,除非我能明確地知道此控制物件是多餘的,否則現在先行加入,並不是一個壞主意。

我們並不打算一開始,就可以一口氣找到全部的物件,不要忘記,系統是逐漸演進的。

其次,一個物件也有可能是由數個物件組合(Composite)而成,到真正實作時,仍有實作上的考量。

接著,可以透過合作圖(Collaboration diagrams)來說明上述物件之間的互動關係,在此,我們不打算將所有的圖型展示出來,僅就「連線作業」的合作圖來做代表。

上圖顯示Client端透過連線介面,輸入所需的資訊(包含欲連接的對象位置以及聊天者帳號),並且開始進行連線。

Client藉由Client 端的連線處理物件,與聊天室建立連線並登錄系統,因為每一個連線處理物件僅能夠單向聯繫,因此,聊天室系統為了與Client端建立雙邊聯繫,必須建立一個用來連接 Client端的Server端連線處理物件。

於是聊天室系統待Client登錄後,產生一個對應於Client的連線處理物件,即是Server 端連線處理物件,並且連接到Client端,最後將此連線處理物件加入清單內。

假如初始階段的UseCase模型,需要以使用者可以理解的方式來說明,那麼進入分析的詳述階段,就必須盡量轉換成開發者可以接受的方式。

當然,系統分析初期,尚不必須完全如此。

我一面將UseCase模型的各項情節,嘗試以互動圖(Interactiondiagram)的方式來表示,同時可以思考出更多的物件。

注意,筆者以「思考」這個字眼的意含,當我們一方面製圖時,同時思考物件如何互動,有時我們會發現,需要更專門的物件來負責某項任務,那麼就嘗試建構這樣的物件來負責這項事務。

我們習慣以「責任(responsibility)」來思索必要的物件,以及其必須扮演的角色,同時,不要忘記以「系統架構」為重要的指引。

以下為各情節的循序圖(Sequence diagram): 【初步分析模型】之「連線」循序圖(一) 【初步分析模型】之「連線」循序圖(二) 【初步分析模型】之「離線」循序圖 【初步分析模型】之「取得線上使用者清單」循序圖 【初步分析模型】之「訊息收發」循序圖 【初步分析模型】之「監控Client」循序圖 至於是否要將所有互動的情況,以圖型繪製出來,這個問題很難回答。

思索愈細密,對系統的實作有好處,然而不得不考慮時間及成本的因素。

若加上系統有可能變動的情形,維護這些圖型及相關文件,也是另一種問題。

就算你打算運用塑模來產生程式碼,那也是詳述階段後期與建構階段時所需考量的,假若你不打算這麼做,甚至沒有一套繪圖的工具,那麼圖型夠用就好。

關於這一點,讀者可以參考 MartinFowler的《為何要使用 UML?》一文所述。

直到現在為止,我們可以將找到的物件,繪製成以下的類別圖(Class diagram)。

習慣上,我會省略與UI(UserInterface;使用者介面)相關的物件,而把重點鎖定在控制物件及實體物件上面。

把UI 放到系統設計階段有個好處,那就是與實際開發工具所提供的UI元件,或者ThirdParty廠商所提供的元件做結合。

當然,你要自訂UI 介面的情況是個例外,如果這個範例有需要自製的UI,那就提前分析,提早做準備。

到目前為止,我只是針對類別及其間的關係繪製類別圖(Class diagram),並未詳述類別的屬性、操作(或訊息操作),待到確認上述的類別結構沒有遺漏後,再將循序圖中,物件需反應的訊息操作加入類別圖中。

其次,製作類別圖有時需要應用過去的經驗,或者從別人身上所學習到的經驗。

我在上述的類別結構中,加入 Iterator(反覆)[GOF]這個樣式(Patterns),主要目的是協助系統巡航「使用者連線清單(TalkerList)」,雖然這看似有點違反Kent所主張的「Do TheSimplestThingthatCouldPossiblyWork(只做最簡單可以正常運作的設計) 」,但就像MartinFowler於《Is DesignDead?》一文所說,「What onEarthisSimplicityAnyway(究竟什麼是簡單) 」。

對於目前就加入IteratorPatterns 或許對初學者有點困難,然而透過物件導向設計原則(Design Principle)與軟體重整(Refactoring)這類技術,最後得到的也可能是這樣的結果。

關於上述的這些議題(DesignPatterns、OO DesignPrinciple、Refactoring),請讀者自行參考相關文獻。

設計樣式(DesignPatterns)該不該出現於分析模型?相同的問題是,分析樣式(Analysis Patterns)是否可以延至設計模型中才出現?許多人受到樣式中「分析」、「設計」之詞的迷惑,而忘卻「樣式」的主要目的。

Christopher Alexander 談及樣式,認為「每一個樣式描述一個在我們週遭一再重複發生的問題,接著敘述問題核心的解決方案,你可以一而再,再而三的使用這個解決方法,而無須重複做相同的解決過程」。

Martin Fowler則認為「樣式(patterns)描述做事的共通方法」,同時談到「當你在做分析(analysis)、設計(design)、寫程式(coding)或者專案管理(project management)時,你應該找尋任何可用的樣式(patterns),它們可以為你帶來不少的幫助」(參考:《UML DistilledSecondEdition》中譯本名為《UML 精華第二版》,趙光正譯)。

對筆者而言,分析樣式是用來解決領域上的問題(這也說明它為何稱為分析樣式的原因),而設計樣式是用來解決設計的問題,關於這點,應該是大家所認同的。

但問題在於設計樣式是否可以出現在分析模型?亦或分析樣 式是否可以延至設計模型中?我的答案是:「可以」。

我們看一下設計樣式是甚麼,在《Design Patterns》中談論「設計樣式用來辨識所包含的類別和實例(instances),它們的角色、協作方式,以及職責分配。

每一個設計樣式著重在一個特定的物件導向設計問題,或設計要點,描述什麼時候使用它,在某些設計限定條件下,是否還能使用,使用的效果,以及如何取捨。

」注意到「用來辨識所包含的類別和實例(instances),它們的角色、協作方式,以及職責分配」這段話,執行分析塑模時,我們同樣要做這些工作,José EduardoZindelDeboni在《A designpatterntomodelCORBAcomponentsinUMLanalysisdiagrams》中,談論如何運用 DesignPattern在UML分析圖型中,塑造CORBA元件的模型。

Luke Hohmann在《The BenefitsandDrawbacksofDeliberatelyIntertwiningPatternsandDomainAnalysis》文章裡,也談論到「當滲入設計樣式或語言用語(language idiom)的知識到分析時,許多不可思議的編織(intertwining)方式會發生」,他建議分析者必須了解設計樣式,同時可以用這些樣式來解決分析及實作時的問題,並且提前避免犯了一些共通的錯誤。

如果在分析階段中使用設計樣式或程式語言的習慣用語,可以協助我們找出類別,分配這些類別的角色及職責,並且可以早早避免犯過去共通的錯誤,何樂不為。

至於在漸進式及反覆式的開發中,進行到設計模型時,不免會遇到或發現新的分析概念,或者遇到需求的改變,此時都是運用分析樣式的時機。

Craig Larman在《Applying UMLandPatterns》(中譯本名為《活學活用 UML與樣式》,趙光正譯)談到「除了在設計模型內存在一個新建立的軟體類別外,那也是一種領域概念(domain concept)。

在設計及編程的期間,去發現值得注意的領域概念,並且對需求有更深入的理解(refined understanding),這是正常且普遍的現象,反覆的開發(iterativedevelopment)即是支持這類漸增的發現情況」。

記得系統是演進式地進行,而非瀑布式(一次分析、一次設計)的開發流程。

另外,或許讀者已經發現,上述類別圖與循序圖之間,已經存在某種差異。

勿忘了系統是一種逐漸演進的過程,此時是有必要變更之前的循序圖,更進而將UseCase 模型的情節描述,轉換成軟體開發者觀點的敘述。

我保留原先的視圖,不代表實際作業時,不用對原先的圖型進行修改。

如果先前的圖型文件很重要,保留它們以便於追蹤(Trace);如果你是徒手畫圖,同時這些圖型也達成溝通的目的,存不存在並不重要,那就像 MartinFowler 所建議的一般,擦掉(或丟掉)算了。

我不打算把修改過的循序圖展現一次,至程式原型製作時,各位可以看到比現在更完整的循序圖,我以下所做的,是把類別圖更進一步推展,並加入更多的想法。

拿上面的兩個類別圖與之前的比較,應該有明顯的不同,我將Receiver與Sender 兩個物件合併,原因是它們所負責的操作僅有一項,沒有必要使用兩個物件(或介面)來分別執行;當然,假若發現某個物件負責的操作項目太多太雜,或者有違物件導向設計原則,此時就有必要重新分配。

這種分解重組的動作,我稱呼其為「模型重整」(Model Refactoring)。

 



請為這篇文章評分?