建模心法(2)——邁出建模第一步

原文地址:http://www.cnblogs.com/1-2-3/archive/2008/08/04/model-method-part1.html

原文作者:景春雷

??????????????????? 一錯再錯的這故事才精彩
??????????????????????????????????????——樸樹 《我愛你再見》

摘要

????? 即使讀了再多的書、跟過再多的項目,到了需要自己創建領域模型的時候,還是感覺不知從哪兒下手。就像即使看過再多的小說,到了自己想寫小說的時候,仍會感 覺無從下筆……本文將給出3個實用的建模心法,并通過一個實際項目介紹如何應用USM三視圖法邁出建模第一步。

殷六俠即將平生第一次下山做任務



殷六俠來到張三豐的禪房。

殷六俠:“師傅,弟子就要下山去了,特來向師傅告別。”
張三豐:“梨亭啊,雖然你平時讀書很用功,也跟著師兄們做了一些項目,但這次畢竟是第一次獨力建模,心里有沒有譜呀?”
殷六俠:“說實話,弟子現在大腦一片空白。”
張三豐:“……”
殷六俠:“弟子雖然已經把《領域驅動開發心經》、《設計模式真經》、《分析模式真經》讀了個滾瓜爛熟,可是到了用的時候,還是有一種無處著力的感覺。”
張三豐:“簡直都不知道從哪開始對不對?這是很正常的。這次事出緊急,只能由你一個人立即趕往同仁堂,實在有些難為你了。不過好在現在科技發達了,有什么問題可以隨時用QQ與為師聯系。時候不早了,你快些動身吧。”
殷六俠:“那徒兒就告退了,師傅保重!”
張三豐:“等一等,你進禪房之前可曾聽到為師鼓瑟?”
殷六俠:“師傅是否想說建模就如同鼓瑟,音樂的好聽與否并不因為單獨的某個音符的高低短長,而是所有音符連續起來的效果?”
張三豐:“好,很好。我的七個徒弟里面,除了你五師哥,就是你悟性最高了。快快下山去吧。”
殷六俠:“徒兒告退。”

第一天的QQ聊天記錄

殷六俠:師傅,弟子已經順利到達同仁堂,這邊的領域專家用一上午的時間向我介紹了一下住院部的業務,我整理出了十幾個用例:(限于篇幅,這里僅列出3個)
????? 用例(use case) 由用戶的目標聯系在一起的一組場景
??????場景(scenario) 一系列表述用戶和系統之間一次交互的步驟。


名詞法為什么行不通

張三豐
:很好,用例做得挺不錯的,接下來你打算做什么?
殷六俠:謝謝師傅夸獎,做用例其實并不難,只要把領域專家說的東西稍加整理就行了。弟子接下來就準備根據用例制作領域 模型了。我想用名詞法,首先找到用例中的名詞,例如“收款員”就是實體,與它相關的動詞,例如“提交入院登記”就是實體的一個方法。然后我再根據面向對象 設計的原則和設計模式對類和職責進行調整。
張三豐:很遺憾,我不得不指出你犯了一個初學者常犯的錯誤——把用例中的名詞等同于領域模型里的實體。事實上,用例代表的是系統的外觀,用例中的名詞和系統中的實體沒有任何聯系。
殷六俠:可是,領域模型里難道不該有一個叫“收款員”的實體么?
張三豐:沒錯,領域模型里會有一個叫“收款員”的實體,不過它和用例里面的收款員可不是一回事。用例里面的收款員處于系統外部,是一個活生生的人;而領域模型里的“收款員”實體,確切的說應該叫“收款員基本信息”,這個實體只知道收款員的姓名、性別、年齡和權限等信息。
殷六俠:我注意到您用了“知道”這個詞,您是不是想說“收款員基本信息”實體知道得太少而無法承擔“提交入院登記”這個職責呢?
張三豐:記得《蜘蛛俠》里面的經典臺詞吧?“能力越大,責任就越大。”對于類來說,知道的越多,操作就越多。一個類有 2種職責:1)知識性職責,包括屬性、關聯和無副作用的方法;2)操作性職責,就是指類的含副作用的方法。一個原則就是,要把職責分配給最容易取得它所需 的信息的那個類。
殷六俠:可是,建模的時候會面臨著3個問題:“模型里要有哪些類?類之間如何關聯?類有哪些職責?”應該首先考慮哪個問題呢?或者說哪個問題比較重要呢?
張三豐:記得有句古話叫“程序=數據結構+算法”吧?那么你說是先有數據結構呢?還是先有算法?
殷六俠:若要為解決某個問題設計一個算法,雖然有可能會先考慮數據結構或算法,但是其實它們兩個是相互配合、無法單獨工作的吧?也就是說,它們在理論上應該是同時產生、同等重要的吧?
張三豐:沒錯。而類是把數據結構和算法捏到了一起,所以理論上這三個問題也是被同時解決的。
殷六俠:可是恕徒兒愚笨,要同時思考這三個問題我可實在是辦不到。
張三豐:好在實體類還有一個更重要的職責:它要具有延續性和生命周期,并且以identity而不是其它的屬性來相互區別。我們要首先按這個職責來構建實體和關聯,然后再考慮實體的其它職責,這樣就簡單多了。
殷六俠:那么設計模式是否對找出實體有所幫助呢?
張三豐:應該說用處不大。因為建模的目的是構建一個領域模型來仿真現實的業務,它的結構恰巧與設計模式里的類結構相同 的情況并不多見。需要注意的是,設計模式關注的主要是如何應用OO的技術手段(接口和多態)來簡化設計和增加彈性,它們的關注點是不同的。現實業務里組合 的情況很常見,例如合同包含一些產品,產品由部件組成,但是卻不一定需要使用Composite模式那樣的類結構,因為可能并不需要Composite模 式所提供的那么強大的一致性和彈性。如果勉強使用Composite模式反而會使模型難以理解,還會由于使用了過窄的接口導致大量的向下轉型操作,為 Client代碼增加了不必要的復雜性。設計模式確實提供了誘人的一致性和高內聚性,但是你得首先找到領域中的一致性才行。
殷六俠:那我該如何找出實體類呢?實體實體,就是實際存在的物體吧?我注意到每個患者床上都掛著一個床頭卡,那么模型里應該有一個床頭卡實體吧?還有我可以去收集所有的報表,然后從這些報表里的字段來分析出該有哪些實體。
張三豐:我希望你從一開始就有一個清醒的認識:建模是一項無中生有的、100%的創造性工作,并不存在某種方法或公式 可以讓你從用例或實際物體里推導出領域模型。領域模型是“分析”不出來的,它是被“設計”出來的。所以,領域模型里會有一些現實世界里并不存在的實體,當 然也會有與現實世界里的物體同名的實體,但是它只是表現現實物體的某個方面,所以它的職責也就很可能與現實物體不同。至于報表,一般多是取自幾個實體中的 數據,還要進行匯總等統計操作,所以比較適合用來驗證模型,而不是一開的創建模型的工作。
殷六俠:唉,師傅,您越說我就越糊涂,恐怕弟子是要辜負師傅的重托了……
張三豐:別急,其實建模還是有一些實用技巧的,待為師傳你建模心法。呃,今天時候不早了,明天再說吧。拜拜
殷六俠:師傅晚安。

殷六俠回到客棧,周圍突然一下子變黑了,屏幕上出現一行小字:“正在存盤……”

第二天的QQ聊天記錄

殷六俠:師傅早。
張三豐:早。昨天說到哪了?對,建模心法。先傳你建模心法1。

建模心法1 尋找線索實體。

殷六俠:什么叫線索實體?
張三豐:就是生命周期恰好貫穿整個業務流程的那個實體。這個實體就像一條線,將整個業務流程中的其它實體串起來,形成星型的結構。
殷六俠:我明白了,例如一個企業的銷售業務就是簽訂合同、執行合同,那么“合同”就是這樣的一個線索實體。
張三豐:沒錯。
殷六俠:讓我想想,對于住院管理來說,這個線索實體的生命周期應該在患者入院時開始,患者出院時結束。“病歷本”符合這一條件,不過讓其它的實體都關聯“病歷本”似乎不大自然。由于患者可能多次住院,所以患者這個實體的生命周期顯然過長而不適合作為線索實體。
張三豐:很好。
殷六俠:這個線索實體可以定義為“患者的一次住院”。嗯……可以叫“住院履歷”,或者干脆叫“住院記錄”好了。
張三豐:這個名字還算湊合吧。起一個好名字還是很難的,以后有空多去武當山下的釀名齋坐坐。
殷六俠:是,師傅。有了這個線索實體類,其它的幾個相關的實體也很自然地產生了。



張三豐
:看上去挺不錯的,不過我要提醒你,領域模型是要能滿足所有用例的所有場景的,這個模型里沒有包括費用相關的實體呀。
殷六俠:是啊,直覺上費用的處理挺復雜的。
張三豐:你的直覺很正確。現在為師傳你建模心法2。

建模心法2 尋找相似場景。

張三豐:如果幾個用例中都包含相似的場景,例如“計費”,就可以把這些相似的場景抽取出來成為一個單獨的用例,再讓其 它用例包含(include)這個被抽取出來的用例,不過這不是必須的。最重要的是你要認識到尋找相似場景的意義。越多的用例包含這個相似場景,就說明這 個場景的業務越復雜,設計不當的可能性越高;將來重構的成本也越大。換句話說就是風險越發的高,所以更需要你加倍仔細、小心地處理。
殷六俠:您是說我們要設計一個實體-關系結構,可以滿足所有的相似場景?感覺好難的說。
張三豐:沒錯,有時會感覺太復雜而無法把握,這時可以試試建模心法3。

建模心法3 使用示例場景(Sample Scenario),尋找一致性。

張三豐:示例場景是一組(最好是連續的)模擬真實業務的場景。例如和費用相關的示例場景為:
場景一:患者入院登記。交預繳金200元。申請獲得500元擔保金。為醫保患者,醫保卡內有1000元。
場景二:第一天消費感冒通一盒(50元)、抽血一次(30元)、床位費(100元)
場景三:經申請,擔保金額度升為1000元。另,護士重新讀取了醫保卡,醫保卡里的余額是2000元。
場景三:鑲金牙(1000元,走現金帳戶),擔保金+賬戶余額=100元小于最低預繳金額(200元,系統參數),要求續費
場景四:續交現金預繳金2000元。
場景五:護士刷醫保卡繳費。
????? 最好與領域專家共同制作示例場景。要涵蓋所有可能的情況,同時注意不要包含現實業務中不存在的情況以避免不必要的復雜性。如果領域專家指出某種情況是不存 在的,應該進一步追問其原因。原因可能是“目前為止還從未出現過這種情況,雖然理論上是合理的”,“這種情況是違反法律或行規的”,“這么做將傷害公司或 客戶的利益”,“為了方便某個部門或某類員工的工作”、“也許這么做會更合算,但是我們領導偏偏就要求要按現在的做法去做”等等。無論是何種原因,都可能 成為未來的變更點。雖然目前的設計不必理會這些不可能情況,但是可以思考一下將來發生變更時如何修改現有設計,以此為契機很可能會發現更為簡單且富有彈性 的設計。
????? 上面的示例場景是不完全的,因為沒有涉及退費相關的場景(抱歉限于篇幅沒有給出退費相關的用例),就以上面的5個示例場景,該如何設計領域模型呢?
????? 可以注意到示例場景中存在兩類金額:預繳金和擔保金。執行某醫囑時可能從預繳金中扣錢,但是也可能從醫保卡中扣錢。出于需要為患者打印每日費用明細(抱歉限于篇幅沒有給出這個用例)和退費,需要記錄每筆費用,這讓你想到了什么?
殷六俠:這讓我想到可以試試賬戶+變更記錄這個模式(關于常用的分析模式,我打算以后再寫幾篇來專門介紹),讓我仔細想想……

1小時之后

殷六俠:我想到醫保卡余額與擔保金在概念上很相似,這樣就可以一致地處理醫保卡賬戶和現金賬戶了。



殷六俠:領域模型變成這樣:



殷六俠:示例場景確實給了我不少感性認識。
張三豐:隨著OOA&D的流行,人們普遍認同一開始建模的時候不應考慮實現細節,而應把注意力集中在對領域的 深刻理解上。領域模型里的對象結構與實際的數據庫表結構可以有很大的不同;實體間的關聯也不一定非得實現為外鍵關聯……不過請不要把可以忽略實現細節等同 于可以忽略細節領域知識。正所謂“細節就是魔鬼”,醉心于抽象和一致性,而沒有把同等甚至更多的精力投入到發現不一致的細微之處上,實在是一種很危險的做 法。所謂“具而不抽則罔,抽而不具則殆”,讓思維在抽象和具體之間來回移動才更有效。示例場景還給了你一個“橫切”用例的機會,可以讓你對業務有一個更加 立體的認識。
殷六俠:制作示例場景還是一個發現遺漏用例和提出尖銳問題的好機會。例如剛剛我就很自然地想到“擔保金只是對現金賬戶 來說的么?還是對現金賬戶和醫保賬戶同時有效?例如當現金賬戶和醫保卡里面的錢都用光了,而擔保金為3000元時,這時計費只能走現金賬戶還是也可以走醫 保賬戶呢?”

小結 USM三視圖法

????? 運用本文介紹的USM(用例-示例場景-領域模型)三視圖法,可令 Modeler 從不同視角觀察企業業務,讓思維在抽象和具體之間來回移動,互相促進、完善,發現未曾注意的細節,找出概念上的一致性,不斷加深對領域的理解。希望USM 三視圖法成為虛空中的一塊踏腳石,幫助 Modeler 邁出建模第一步。
?


參考文獻

Craig Larman,
UML和模式應用。機械工業出版社,2004.
Martin Fowler 著,徐家福 譯,UML 精粹(第2版)標準對象建模語言簡明指南。清華大學出版社,2002。
Eric Evans, 領域驅動設計(影印版)。人民郵電出版社,2007。
Martin Fowler, 分析模式(影印版)。中國電力出版社,2003.
RicCC,分析模式讀書筆記。博客園,2008.

轉載于:https://www.cnblogs.com/jiushini/archive/2012/05/27/2520522.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274779.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274779.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274779.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Web:你知道我這十幾年是怎么過來的嗎?!

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列1989 …

設計師更高效_如何丟掉我的工作使我成為一名更好的設計師

設計師更高效I lost my job a few times early on in my design career. In the process of getting back up after a job loss, it has made me a better designer not only in terms of hard skills but the soft skills required to be more resilient and empathetic, whic…

【ASP.NET】登陸成功后如何跳轉到上一個頁面

當用戶瀏覽網頁的時候會在某個地方需要用戶登陸才能繼續瀏覽,用戶登陸之后會自動跳轉到剛剛瀏覽的頁面。這個步驟是怎么實現的呢?net小伙在查閱相關資料實踐之后終于明白了,其實很簡單,先分享給大家吧。 當用戶在瀏覽一個頁面的時…

4月,誠邀你參加源碼共讀,學會看源碼,打開新世界!開闊視野

大家好,我是若川。很多關注我的新朋友可能不知道我組織了源碼共讀活動~也有很多人不知道我是誰。有人以為我是80后。有人以為我是全職自媒體等等。若川的 2021 年度總結,彈指之間 這篇文章寫了我是16年畢業的,或許有些啟發。源碼共讀按照從易…

bt709和srgb_選擇用于多用途視頻編輯和色彩校正的顯示器— sRGB,DCI-P3,REC 709

bt709和srgb**Note from the author: if you enjoy this article, please follow me or this publication for more video production and marketing related content.****作者注:如果您喜歡本文,請關注我或此出版物以獲取更多與視頻制作和營銷相關的內容…

超4000人參加源碼共讀,喊你來一起學習成長~打開新世界

大家好,我是若川。很多關注我的新朋友可能不知道我組織了源碼共讀活動~也有很多人不知道我是誰。有人以為我是80后。有人以為我是全職自媒體等等。若川的 2021 年度總結,彈指之間 這篇文章寫了我是16年畢業的,或許有些啟發。源碼共讀按照從易…

figma設計_如何在Figma中構建設計入門套件(第二部分)

figma設計Figma教程 (Figma Tutorial) With this short, but informative Tutorial Series I aim to show you how to build the solid foundations of a powerful, and versatile Design Starter Kit, enabling you to start your next project in Figma faster than ever bef…

Hibernate 簡介(百度)

Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在…

GitHub 最受歡迎的Top 20 JavaScript 項目

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列今天來…

java反編譯,eclipse支持插件

http://java.decompiler.free.fr/?qjdeclipse 按照說明 在eclipse更新插件就可以。 這樣 在一些 閉源的jar文件,你也可以看到 大致的源碼。(公司 知道如何 加密混淆 java代碼或class文件,居然無法使用jd-gui瀏覽源碼) 而&#xf…

unity vr 交互_基于手動的VR / MR交互,用于刪除實體

unity vr 交互Deleting an entity or closing an application is one of the most ubiquitous operations performed in any application. It is necessary for the organization of the data. On the computer, there are multiple ways to delete a file like cmd delete, d…

手把手帶你走進Babel的編譯世界

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列前言談…

iPhone/Mac Objective-C內存管理教程和原理剖析(二)口訣與范式轉

版權聲明 此文版權歸作者Vince Yuan (vince.yuan#gmail.com)所有。歡迎非營利性轉載,轉載時必須包含原始鏈接http://vinceyuan.cnblogs.com,且必須包含此版權聲明的完整內容。 版本 1.1 發表于2010-03-08 二 口訣與范式 1 口訣。 1.1 …

同態加密應用_重新設計具有同態性的銀行應用

同態加密應用Catering user preference is undoubtedly a never-ending task. End of the day, it takes all sorts to make a world. For that reason, it is deemed important to design with the accent of communicating core business value, and resolving user needs wi…

(字節/華為/美團)前端面經記錄冷冷清清的金三銀四

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列從畢業…

PHP連接PGSQL

function conn($hostName,$Login,$Password,$dbName,$Port) //建立目標數據庫連接 {$conn &ADONewConnection(postgres8);$conn->debug false; //true時adodb將在頁面顯示debug信息$conn->LogSQL(false); //true時adodb將建立adodb_sqllog表記錄每次sql操作$conn-&…

netflix_Netflix播放按鈕剖析

netflixWe will develop a play pause button similar to the one the Netflix video player has.我們將開發一個類似于Netflix視頻播放器的播放暫停按鈕。 Since Swift has replaced Objective-C as the default development language for iOS, the same will apply to Swift…

TypeScript 終極初學者指南

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列在過去…

繼承與多態(六)

繼承 1.繼承 a。.直接在類的后面加上冒號“:”后面跟基類,就該類就繼承了基類的一切特性了。 b。private類不能被繼承,只有public、protected類能被繼承。 c。private類不里面所有的屬性和方法都不能被外界訪問,只有他自己可以。 …

標記偏見_如何(巧妙地)扭曲視覺效果以支持您的偏見敘事

標記偏見Data is important — it is the logical justification for world-changing decisions. Unfortunately, arrays of numbers don’t tell as interpretable a story as a picture does, providing an insatiable need for data visualizations.數據很重要-這是改變世界…