Cyh的博客

          Email:kissyan4916@163.com
          posts - 26, comments - 19, trackbacks - 0, articles - 220

          ~ 第9章:領域模型

          • 目標 1》確定與當前迭代相關的概念類 2》創建初始的領域模型 3》為模型建立適當的屬性和關聯。

            簡介      領域模型是OO分析中最重要的和經典的模型。它闡述了領域中的重要概念。領域模型可以作為設計某些軟件對象的靈感來源,也將作為在案例研究中所探討的幾個制品的輸入。本章還將展示UML表示法上OOA/D知識的價值。基本表示法非常容易,但是對于有用模型的一些深奧的建模準則,則需要數周或數月才能掌握。     

                  和敏捷建模和UP精神中的所有事物一樣,領域模型也是可選制品。在圖9-1中所示的UP制品相互影響力中強調了領域模型。領域模型的范圍限定于當前迭代所開發的用例場景,領域模型能夠被不斷地演進用以展示相關的重要概念。相關的用例概念和專家的觀點將作為創建領域模型的輸入。反過來,該模型又會影響操作契約、詞匯表和設計模型,尤其是設計模型中領域層(domain layer)的軟件對象。

            示例      圖9-2展示了以UML類圖(class diagram)表示法繪制的部分領域模型。對領域模型應用UML類圖表示法會產生概念透視圖(conceptual perspective)模型。 確定一組概念類是OO分析的核心。如果能夠通過熟練和快速(就是說,每次早期迭代不超過幾個小時)的調查來完成這項工作,那么通常會在設計過程中得到回報,因為領域模型能夠支持更好的理解和溝通。準則:避免瀑布思維傾向,為完成詳盡或“正確”的領域模型而進行大量建模工作。這些方式都應避免,并且這種過量的建模工作反而會導致分析停滯,這種調查幾乎不會有什么回報。

            什么是領域模型      這一精髓的面向對象分析步驟是從領域到重要概念或對象的分解。領域模型(domain model)是對領域類或現實世界中對象的可視化表示。領域模型也稱為概念模型、領域對象模型和分析對象模型。定義:在UP中,術語"領域模型"指的是對現實世界概念類的表示,而非軟件對象的表示。該術語并不是指用來描述軟件類、軟件架構領域層或有職責軟件對象的一組圖。UP對領域模型的定義是,可以在業務建模科目中創建的制品之一。更準確地講,UP領域模型是UP業務對象模型(BOM)的特化,“專用于解釋業務領域中重要的‘事物’和產品”也就是說,領域模型專注于特定領域。更為廣泛的BOM是擴展的、通常十分龐大和難以創建的多領域模型,BOM覆蓋整個業務及其所有子域,本章并不涵蓋這部分內容,并且也不提倡創建BOM(因為需要在是實現前進行大量建模)。

                  應用UML表示法,領域模型被描述為一組沒有定義操作(方法的特征標記)的類圖)(class diagram)。它提供了概念透視圖。它可以展示:

            • 領域對象或概念類。
            • 概念類之間的關聯
            • 概念類的屬性。

            定義:為什么把領域模型稱為“可視化字典”

                  請仔細觀察圖9-2.看看它是如何對領域詞匯或概念進行可視化和關聯的。領域模型還顯示了概念類的抽象。因為這種抽象可以表達其他大量事物,例如登陸、銷售等。

                  領域模型(使用UML表示法)描述的信息也可以采用純文本方式(UP詞匯表)表示。但是在可視化預言中更容易理解這些術語,特別是它們之間的關系,因為我們的思維更擅長理解形象的元素和線條連接。因此,領域模型是可視化字典,表示領域的重要抽象、領域詞匯和領域的內容信息。

            定義:領域模型是軟件業務對象圖嗎      如圖9-3所示,UP領域模型是對所關注的現實世界領域中事物的可視化,而不是諸如Java或C#類的軟件對象,或有職責軟件對象(參見圖9-4)。因此以下元素不適用于領域模型:

            • 軟件制品,例如窗口或數據庫,除非已建模的領域是針對軟件概念的,例如圖形化用戶界面的模型。
            • 職責或方法。

            定義:“領域模型”的兩個傳統含義      在UP及本章中“領域模型”是現實世界中對象的概念透視圖,而非軟件透視圖。但這一術語是多義的,也用來表示“軟件對象領的領域層”也就是說,在表示層或UI層之下的軟件對象層是由領域對象(domain object)組成的--領域對象是表示問題領域空間事物的軟件對象,并且與“業務邏輯”或“領域邏輯”方法相關。我通常會使用領域層(domain layer)來表示領域模型針對軟件的第二個含義,因為領域層也十分通用。

             

            定義:什么概念類      領域模型闡述領域中的概念類或詞匯。概念類是思想、事物或對象。更正式的講,概念類可以從其符號、內涵和外延來考慮。

            • 符號:表示概念類的詞語或圖形
            • 內涵:概念類的定義
            • 概念類所適用的一組示例

            定義:領域模型和數據模型是一回事嗎       領域模型不是數據模型(通過對數據模型的定義來表示存儲于某處的持久性數據),所以在領域模型里,并不會排除需求中沒有明確要求記錄其相關信息的類(這是對關系數據庫進行數據建模的常見標準,但與領域建模無關),也不會排除沒有屬性的概念類。例如,沒有屬性的概念類是合法的,或者在領域內充當純行為角色而不是信息角色的概念類也是有效的。

            動機:為什么要創建領域模型       領域模型和領域層使用相似的命名可以減少軟件表示與我們頭腦中的領域模型之間的差異。    動機:降低與OO建模之間的表示差異    這是OO的關鍵思想:領域層軟件類的名稱要源于領域模型中的名稱,以使對象具有源于領域的信息和職責。圖9-6闡述了這一思想。這樣可以減少我們的思維與軟件模型之間的表示差異。同事,這并非只是哲學上的考究--對時間與金錢也會有實際的影響。

            準則:如何創建領域模型       1、尋找概念類 2、將其繪制為UML類圖中的類 3、添加關聯和屬性

            準則:如何找到概念類       既然領域模型表示的是概念類,那么關鍵問題是如何才能找到概念類。找到概念類的三條策略   1、重用和修改現有的模型。這是首要、最佳且最簡單的方法,如果條件許可,通常從這一步開始。在許多常見領域中都存已發布的、繪制精細的領域模型和數據模型(可以修改為領域模型),這些領域包括庫存、金融、衛生等等。我所參考的書籍包括Martin Fowler的《分析模式》(Analysis Patterns)、David hay的Data Model Patterns和Len Silverston的Data Model Resource Book(卷1和卷2) 2、使用分類列表   3、確定名詞短語      重用現有的模型是最好的辦法,但超出了本書的范圍。第二個方法(使用分類列表)也很有效。   方法2:使用分類列表   我們可以通過制作概念類候選列表來開始創建領域模型。參看表9-1。   方法3:通過識別名詞短語尋找概念類    在【Abbot83】中所建議的另一種有效(因為簡單)技術是語言分析(linguistic analysis),即在對領域的文本性描述中識別名詞和名詞短語,將其作為候選的概念類或屬性。    準則:使用這種方法時必須小心。不可能存在名詞到類的映射機制,并且自然語言中的詞語具有二義性。領域模型是重要領域概念和詞匯的可視化。那么從哪里找到這些術語?其中某些術語來源于用例。另外一些術語則源于其他文檔,或是專家的想法。無論如何,用例都是挖掘名詞短語的重要來源之一。

            示例:尋找和描繪概念類       參見圖9-7 圖9-8

            準則:敏捷建模--繪制類圖的草圖       注意圖9-8中UML類圖的這種草圖風格,讓類框的底部和右側呈開發狀態。這樣可以在發現新元素時對類方便地進行擴展。

            準則:敏捷建模--是否要使用工具維護模型      敏捷模型在創建后通常很快就被拋棄了(即使這樣,如果你使用白板的話,我還是建議用數據相機拍下來)。基于這種觀點,則沒有理由去維護或更新這些模型。但是這也不意味著更新模型就是錯的。通常,進化的軟件領域層對大部分重要術語會給予提示,而且長生命期的OO分析領域模型不會增加價值。

            準則:報表對象--模型中是否要包括“票據”

            準則:像地圖繪制者一樣思考;使用領域術語      地圖繪制者的策略既可用于地圖,也可以用于領域模型。準則: 以地圖繪制者的工作思維創建領域模型:1》使用地域中現有的名稱 2》排除無關或超出范圍的特性 3》不用憑空增加事物

            準則:如何對非現實世界建模      有些軟件系統的領域與自然領域或業務領域幾乎沒有類似之處,例如電信軟件。然而還是有可能為這些領域創建領域模型。此時需要高度的抽象,對常見的非OO設計進行回歸,并且認真吸取領域專家所使用的核心詞匯和概念。

            準則:屬性與類的常見錯誤      在創建領域模型時最常見的錯誤是,把應該是概念類的事物表示為屬性。   準則:如果我們認為某概念類X不是現實世界中的數字或文本,那么X可能是概念類而不是屬性。

            準則:何時使用“描述”類建模       描述類(description class)包含描述其他事物的信息。在[Coad92]中,這種類通常被命名為項目-描述符模式。圖9-9   準則:何時需要描述類   在以下情況下需要增加描述類(例如,ProductDescription)

            • 需要有關商品或服務的描述,獨立于任何商品或服務的現有實例
            • 刪除其所描述事物(如Item)的實例后,導致信息丟失,而這些信息是需要維護的,但是被錯誤地與所刪除的事物關聯起來。
            • 減少冗余或重復信息。

            圖9-10

            關聯      找到并表示出關聯是有助的,這些關聯能夠滿足當前所開發場景的信息需求,并且有助于理解領域。關聯(association)是類(更精確地說,是這些類的實例)之間的關系,表示有意義和值得關聯的連接(圖9-11)在UML中,關聯被定義為“兩個或多個類元之間的語義聯系,涉及這些類元實例之間的連接”。  

                   準則:何時表示關聯   關聯表示了需要持續一段時間的關系,根據語境,可能是幾毫秒或數年。換言之,我們需要記錄哪些對象之間的關系? 由于領域模型是從概念角度出發的,所以是否需要記錄關聯,要基于現實世界的需要,而不是基于軟件的需要,盡管在實現過程中,會有出現大量對關聯的需要。圖9-11關聯。   準則:在領域模型中要考慮如下關聯:1》如果存在需要保持一段時間的關系,將這種語義表示為關聯(“需要記住”的關聯)2》從常見關聯列表中派生的關聯。

                  準則:為什么應該避免加入大量關聯    在具有n個節點的圖中,節點間有(n*(n-1))/2個關聯,這可能是個非常大的數值。連線太多會產生“視覺干擾”,使圖變的混亂,所以要謹慎地增加關聯線。使用本章準則所建議的標準,并且重點關注“需要記住”的關聯。   

                  觀點:關聯是否會在軟件中實現   在領域建模過程中,關聯不是關于數據流、數據庫外鍵聯系、實例變量或軟件方案中的對象連接語句;關聯聲明的是針對現實領域從純概念角度看有意義的關系。也就是說,這些關系的大部分將作為(設計模型和數據模型中的)導航和可見性路徑在軟件中加以實現。但是,領域模型不是數據模型;添加關聯是為了突出我們對重要關系的大致理解,而非記錄對象或數據的結構。

                  應用UML:關聯表示法       關聯被表示為類之間的連線,并冠以首字母大寫的關聯名稱。見圖9-12警告:閱讀導向箭頭對模型來說并不具有特別意義,只是對閱讀圖的人有所幫助

                  準則:在UML中如何對關聯命名      以“類名-動詞短語-類名”的格式為關聯命名,其中的動詞短語構成了可讀的和有意義的順序。諸如“擁有”或“使用”這樣簡單關聯名稱通常是拙劣的,因為這種名稱不會增強我們對領域的理解。關聯名稱應該使用首字母大寫的形式,因為關聯表示的是實例之間鏈接的類元。在UML中,類元應該首字母大寫。以下是復合性關聯名稱的兩種常見并且等價的合法格式:1》Records-current   2》RecordsCurrent

                  應用UML:角色       關聯的每一端稱為角色(role)。角色具有如下可選項: 1》多重性表達式 2》名稱 3》導航 多重性將在后面討論。

                   應用UML:多重性       多重性(multiplicity)定義了類A有多少個實例可以和類B的一個實例關聯(見圖9-13)。在圖9-14中將給出一些多重性表達式的例子。多重性的值表示在特定時刻(而不是某個時間跨度內)有效關聯的實例數量。多重性的值和建模者和軟件開發者的關注角度有關,因為它表達了將要(或可能)在軟件中反映的領域約束。見圖9-15.

                  應用UML:兩個類之間的多重關聯      在UML類圖中,兩個類之間可能會有多重關聯,這并不罕見見圖9-16

                  準則:如何在常見關聯列表中找到關聯      通過使用表9-2中的列表來開始添加關聯。該列表中包含值得考慮的常見類別,對業務系統而言更是如此。

             

              示例:領域模型中的關聯      參見圖9-17和圖9-18

            屬性      確定概念類的屬性是有助的,能夠滿足當前所開發場景的信息需求。屬性(attribute)是對象的邏輯數據值。

                  準則:何時展示屬性       當需求(例如,用例)建議或暗示需要記住信息時,引入屬性。

                  應用UML:屬性表示法      屬性在類框圖的第二格中表示(參見圖9-19)。其類型和其他信息是可選的。在UML中,屬性的完整語法是:  visibility name:type multiplicity = default {property-string},對該表達式譯為中文是: 可見性  名稱:類型  多重性=默認值 {特性表}   參見圖9-20。依照慣例,大部分建模者會假設屬性的可見性為私有的(-),除非有另外表示,所以我通常不會顯式地標出可見性符號。   {readOnly}大概是屬性的{property-string}部分最常用的值。   多重性用來指示可能出現的值,或者可以填充到(集合)屬性中的對象數量。例如,許多領域要求知道某人的名和姓,但是中名是可選的。表達式middleName:[0..1]表示可選值,該屬性可以出現0或1個值。準則:在哪里記錄屬性需求       有些建模者認可只在領域模型中保留這種規格說明,但是我發現這是一種錯誤傾向,并且被擴散了,因為人們往往不去仔細查看領域模型或需求指導。人們也通常不會維護領域模型。   我建議把所有這種屬性需求置于UP詞匯表(UP詞匯表可充當數據字典)。可能我已經花費了一個小時和領域專家一起畫出領域模型的草圖;之后,我可以花費15分鐘瀏覽這個草圖并將其中表示的屬性需求轉移到詞匯表中。另一種方法是,使用工具將UML模型和數據字典統一起來;這樣所有屬性會自動顯示為數據字典的元素。  導出屬性      Sale中的total屬性可以從SalesLineItems中的信息計算或導出。當我們需要表達:這是重要屬性,但是導出的,那么可以使用UML的約定:在屬性名稱前加以"/"符號。 收銀員輸入的數量可以被記錄為SalesLineItem的屬性(參見圖9-21)。但該數量可以從關聯的多重性的實際值計算出來,所以被表示為導出屬性,即可以由其他信息導出的屬性。

                  準則:什么樣的屬性類型是適當的       關注領域模型中的數據類型屬性    通俗的說,大部分屬性類型應該是“簡單”數據類型,例如數字和布爾。通常,屬性的類型不應該是復雜的領域概念,例如Sale或Airport。圖9-22中Cashier類的currentRegister屬性是不合適的,因為其類型是Register,并不是簡單數據類型(例如Number或String)。表達Cashier使用Register的最有效的做法是使用關聯,而不是使用屬性。   準則   領域模型中屬性的類型更應該是數據類型(data type)。十分常見的數據類型包括:Boolean,Date(或DateTime)、Number、Character、String(Text)和Time。其他常見的類型還有Address、Color、Geometrics(Point、Rectangle)、Phone Number、Social Security、Number、Universal Product Code(UPC)、SKU、ZIP或者是郵政編碼、枚舉類型。   準則:通過關聯而不是屬性來表示概念類之間的關系參見圖9-23

                  數據類型      領域模型中的屬性通常應該是數據類型(data type)。一般來說,數據類型是“基本”類型,諸如數字、布爾、字符、字符串和枚舉(例如,尺寸={小,打})。更準確地講,UML術語中的數據類型指的是一組值,而這組值的標識本身不具有任何含義(在我們的模型或系統的語境下)。換言之,對數據類型的等價性檢驗不是基于標識,而是根據值來判斷的。      數據類型值往往是恒定不變的,例如,Integer的實例"5"是不變的;Date的實例“Nov.13,1990”可能也是不變的。而Person實例的lastName屬性可能對不同人有不同的值。   從軟件角度出發,很少會對Integer或Date實例的存儲地址(標識)進行比較,一般是對值進行比較。另一方面,即使Person的不同實例具有相同的屬性值,但還是可以區分和比較其存儲地址,因為其唯一標識的重要性。

                  觀點:代碼中的屬性       在領域模型中建議屬性主要為數據類型,并不意味著C#或Java的屬性只能是簡單的基礎數據類型。領域模型是概念透視圖,不是軟件透視圖。在設計模型中,屬性可以是任何類型。

                  準則:何時定義新的數據類型類       NextGen POS系統需要itemID屬性,可以作為Item或ProductDescription的屬性。注意,該屬性看起來只是數字或字符串,例如,itemID:Integer或itemID:String。 但實際上,該屬性并不僅僅是字符串或數字(商品項目標識符具有子域),更有效的做法是在領域模型中加入類ItemID(或者ItemIdentifier),并且將這個類作為itemID屬性的類型。例如,itemID:ItemIdentifier。表9-3提供了一些準則,指明何時需要在模型中加入數據類型。

                  應用UML:在何處描述這些數據類型類      在領域模型里,ItemID類應該表示為單獨的類嗎?這取決于你想要在圖中強調的事物。既然ItemID是數據類型(實例的唯一標識不用于等價性檢驗),那么可能只會表示在類框的屬性分格中,如圖9-24。采用哪種解決方式取決于如何使用作為溝通工具的領域模型以及領域里概念的重要性。

                  準則:任何屬性都不表示外鍵      領域模型里的屬性不應該用于表示概念類的關系。違反這一原則的常見情況是像在關系數據庫設計中那樣增加一種外鍵屬性,用以關聯兩個類型。參見圖9-25。可以用許多方法來表示對象之間的關系,外鍵就是其中一種方法,我們將推遲到設計時在決定如何實現對象關系,以避免設計蠕變(design creep)。

                  準則:對數量和單位建模       大部分用數字表示的數量不應該表示為純數字。應該給這些數量加上單位,并且通常還需要知道單位之間的轉換關系。領域模型(和軟件)應該具備處理數量的技巧。一般情況下,可以把數量表示為單獨的Quantity類,并且關聯到Unit類。通常可以對Quantity加以規格說明。參見圖9-26

            實例:領域模型中的屬性       參見圖9-27、 9-28

             結論:領域模型是否正確       沒有所謂唯一正確的領域模型。所有模型都是對我們試圖要理解的領域的近似。領域模型主要是在特定群體中用于理解和溝通的工具。有效的領域模型捕獲了當前需求語境下的本質抽象和理解領域所需要的信息,并且可以幫助人們理解領域的概念、術語和關系。

            過程:迭代和進化式領域建模       在迭代開發中,我們會通過若干迭代對領域模型進行增量地演進。在每個迭代中,領域模型都會限定于之前和當前要考慮的場景,而不是膨脹為瀑布風格的“大爆炸”模型,以過早試圖捕獲所有可能的概念類和聯系。因此,只創建部分領域模型反映這一情形,而不涉及其他。   準則:避免瀑布思維傾向,為完成詳盡或“正確”的領域模型而進行大量建模工作,這些方式都應避免,這種過量的建模工作反而會導致分析停滯,這種投入幾乎不會有什么回報。每次迭代的領域模型建模時間不超過幾個小時

                  UP中的領域模型   如表9-4的建議所示,UP中的領域模型通常開始和完成于細化階段。

                  UP業務對象模型與領域模型       UP領域模型是較為少見的UP業務對象模型(BOM)的正式變體。不要與其他對BOM的定義混淆,UP BOM是一種描述整個業務的企業模型。BOM可以用來進行業務過程或再工程,而不依賴于任何軟件應用。引證如下:【UP BOM】作為抽象,描述的是業務人員和業務實體應該怎樣關聯,以及它們如何協作以完成業務。    BOM使用不同的圖(類圖、活動圖和順序圖)來闡述整個企業是如何運轉的(或應該如何運轉)。BOM通常有助于進行企業范圍的業務過程工程,而在創建單個軟件應用時并不常見。因此,UP定義了領域模型,作為BOM的常用制品子集或特化。引證如下:你可以選擇開發“非完整的”業務對象模型,重點解釋領域中的重要“事物”和產品。【...】這些都成為領域模型。



                                                                                                                 --    學海無涯
                  

          主站蜘蛛池模板: 英德市| 嘉峪关市| 雷山县| 安乡县| 保亭| 定日县| 永顺县| 齐齐哈尔市| 始兴县| 桑日县| 绩溪县| 祁阳县| 阳西县| 榆林市| 商洛市| 谢通门县| 伊金霍洛旗| 河西区| 平乡县| 本溪市| 综艺| 大名县| 科尔| 洛川县| 荥经县| 广昌县| 满城县| 德格县| 邳州市| 葵青区| 宣恩县| 马边| 荆门市| 呼伦贝尔市| 金川县| 磐安县| 湖北省| 大城县| 汾西县| 福清市| 桑日县|