建模心法(2)——迈出建模第一步
原文地址:http://www.cnblogs.com/1-2-3/archive/2008/08/04/model-method-part1.html
原文作者:景春雷
??????????????????? 一錯(cuò)再錯(cuò)的這故事才精彩
??????????????????????????????????????——樸樹 《我愛你再見》
摘要
????? 即使讀了再多的書、跟過再多的項(xiàng)目,到了需要自己創(chuàng)建領(lǐng)域模型的時(shí)候,還是感覺不知從哪兒下手。就像即使看過再多的小說,到了自己想寫小說的時(shí)候,仍會(huì)感 覺無(wú)從下筆……本文將給出3個(gè)實(shí)用的建模心法,并通過一個(gè)實(shí)際項(xiàng)目介紹如何應(yīng)用USM三視圖法邁出建模第一步。
殷六俠即將平生第一次下山做任務(wù)
殷六俠來(lái)到張三豐的禪房。
殷六俠:“師傅,弟子就要下山去了,特來(lái)向師傅告別。”
張三豐:“梨亭啊,雖然你平時(shí)讀書很用功,也跟著師兄們做了一些項(xiàng)目,但這次畢竟是第一次獨(dú)力建模,心里有沒有譜呀?”
殷六俠:“說實(shí)話,弟子現(xiàn)在大腦一片空白。”
張三豐:“……”
殷六俠:“弟子雖然已經(jīng)把《領(lǐng)域驅(qū)動(dòng)開發(fā)心經(jīng)》、《設(shè)計(jì)模式真經(jīng)》、《分析模式真經(jīng)》讀了個(gè)滾瓜爛熟,可是到了用的時(shí)候,還是有一種無(wú)處著力的感覺?!?br />張三豐:“簡(jiǎn)直都不知道從哪開始對(duì)不對(duì)?這是很正常的。這次事出緊急,只能由你一個(gè)人立即趕往同仁堂,實(shí)在有些難為你了。不過好在現(xiàn)在科技發(fā)達(dá)了,有什么問題可以隨時(shí)用QQ與為師聯(lián)系。時(shí)候不早了,你快些動(dòng)身吧?!?br />殷六俠:“那徒兒就告退了,師傅保重!”
張三豐:“等一等,你進(jìn)禪房之前可曾聽到為師鼓瑟?”
殷六俠:“師傅是否想說建模就如同鼓瑟,音樂的好聽與否并不因?yàn)閱为?dú)的某個(gè)音符的高低短長(zhǎng),而是所有音符連續(xù)起來(lái)的效果?”
張三豐:“好,很好。我的七個(gè)徒弟里面,除了你五師哥,就是你悟性最高了。快快下山去吧。”
殷六俠:“徒兒告退?!?br />
第一天的QQ聊天記錄
殷六俠:師傅,弟子已經(jīng)順利到達(dá)同仁堂,這邊的領(lǐng)域?qū)<矣靡簧衔绲臅r(shí)間向我介紹了一下住院部的業(yè)務(wù),我整理出了十幾個(gè)用例:(限于篇幅,這里僅列出3個(gè))
????? 用例(use case) 由用戶的目標(biāo)聯(lián)系在一起的一組場(chǎng)景。
??????場(chǎng)景(scenario) 一系列表述用戶和系統(tǒng)之間一次交互的步驟。
名詞法為什么行不通
張三豐:很好,用例做得挺不錯(cuò)的,接下來(lái)你打算做什么?
殷六俠:謝謝師傅夸獎(jiǎng),做用例其實(shí)并不難,只要把領(lǐng)域?qū)<艺f的東西稍加整理就行了。弟子接下來(lái)就準(zhǔn)備根據(jù)用例制作領(lǐng)域 模型了。我想用名詞法,首先找到用例中的名詞,例如“收款員”就是實(shí)體,與它相關(guān)的動(dòng)詞,例如“提交入院登記”就是實(shí)體的一個(gè)方法。然后我再根據(jù)面向?qū)ο?設(shè)計(jì)的原則和設(shè)計(jì)模式對(duì)類和職責(zé)進(jìn)行調(diào)整。
張三豐:很遺憾,我不得不指出你犯了一個(gè)初學(xué)者常犯的錯(cuò)誤——把用例中的名詞等同于領(lǐng)域模型里的實(shí)體。事實(shí)上,用例代表的是系統(tǒng)的外觀,用例中的名詞和系統(tǒng)中的實(shí)體沒有任何聯(lián)系。
殷六俠:可是,領(lǐng)域模型里難道不該有一個(gè)叫“收款員”的實(shí)體么?
張三豐:沒錯(cuò),領(lǐng)域模型里會(huì)有一個(gè)叫“收款員”的實(shí)體,不過它和用例里面的收款員可不是一回事。用例里面的收款員處于系統(tǒng)外部,是一個(gè)活生生的人;而領(lǐng)域模型里的“收款員”實(shí)體,確切的說應(yīng)該叫“收款員基本信息”,這個(gè)實(shí)體只知道收款員的姓名、性別、年齡和權(quán)限等信息。
殷六俠:我注意到您用了“知道”這個(gè)詞,您是不是想說“收款員基本信息”實(shí)體知道得太少而無(wú)法承擔(dān)“提交入院登記”這個(gè)職責(zé)呢?
張三豐:記得《蜘蛛俠》里面的經(jīng)典臺(tái)詞吧?“能力越大,責(zé)任就越大?!睂?duì)于類來(lái)說,知道的越多,操作就越多。一個(gè)類有 2種職責(zé):1)知識(shí)性職責(zé),包括屬性、關(guān)聯(lián)和無(wú)副作用的方法;2)操作性職責(zé),就是指類的含副作用的方法。一個(gè)原則就是,要把職責(zé)分配給最容易取得它所需 的信息的那個(gè)類。
殷六俠:可是,建模的時(shí)候會(huì)面臨著3個(gè)問題:“模型里要有哪些類?類之間如何關(guān)聯(lián)?類有哪些職責(zé)?”應(yīng)該首先考慮哪個(gè)問題呢?或者說哪個(gè)問題比較重要呢?
張三豐:記得有句古話叫“程序=數(shù)據(jù)結(jié)構(gòu)+算法”吧?那么你說是先有數(shù)據(jù)結(jié)構(gòu)呢?還是先有算法?
殷六俠:若要為解決某個(gè)問題設(shè)計(jì)一個(gè)算法,雖然有可能會(huì)先考慮數(shù)據(jù)結(jié)構(gòu)或算法,但是其實(shí)它們兩個(gè)是相互配合、無(wú)法單獨(dú)工作的吧?也就是說,它們?cè)诶碚撋蠎?yīng)該是同時(shí)產(chǎn)生、同等重要的吧?
張三豐:沒錯(cuò)。而類是把數(shù)據(jù)結(jié)構(gòu)和算法捏到了一起,所以理論上這三個(gè)問題也是被同時(shí)解決的。
殷六俠:可是恕徒兒愚笨,要同時(shí)思考這三個(gè)問題我可實(shí)在是辦不到。
張三豐:好在實(shí)體類還有一個(gè)更重要的職責(zé):它要具有延續(xù)性和生命周期,并且以identity而不是其它的屬性來(lái)相互區(qū)別。我們要首先按這個(gè)職責(zé)來(lái)構(gòu)建實(shí)體和關(guān)聯(lián),然后再考慮實(shí)體的其它職責(zé),這樣就簡(jiǎn)單多了。
殷六俠:那么設(shè)計(jì)模式是否對(duì)找出實(shí)體有所幫助呢?
張三豐:應(yīng)該說用處不大。因?yàn)榻5哪康氖菢?gòu)建一個(gè)領(lǐng)域模型來(lái)仿真現(xiàn)實(shí)的業(yè)務(wù),它的結(jié)構(gòu)恰巧與設(shè)計(jì)模式里的類結(jié)構(gòu)相同 的情況并不多見。需要注意的是,設(shè)計(jì)模式關(guān)注的主要是如何應(yīng)用OO的技術(shù)手段(接口和多態(tài))來(lái)簡(jiǎn)化設(shè)計(jì)和增加彈性,它們的關(guān)注點(diǎn)是不同的?,F(xiàn)實(shí)業(yè)務(wù)里組合 的情況很常見,例如合同包含一些產(chǎn)品,產(chǎn)品由部件組成,但是卻不一定需要使用Composite模式那樣的類結(jié)構(gòu),因?yàn)榭赡懿⒉恍枰狢omposite模 式所提供的那么強(qiáng)大的一致性和彈性。如果勉強(qiáng)使用Composite模式反而會(huì)使模型難以理解,還會(huì)由于使用了過窄的接口導(dǎo)致大量的向下轉(zhuǎn)型操作,為 Client代碼增加了不必要的復(fù)雜性。設(shè)計(jì)模式確實(shí)提供了誘人的一致性和高內(nèi)聚性,但是你得首先找到領(lǐng)域中的一致性才行。
殷六俠:那我該如何找出實(shí)體類呢?實(shí)體實(shí)體,就是實(shí)際存在的物體吧?我注意到每個(gè)患者床上都掛著一個(gè)床頭卡,那么模型里應(yīng)該有一個(gè)床頭卡實(shí)體吧?還有我可以去收集所有的報(bào)表,然后從這些報(bào)表里的字段來(lái)分析出該有哪些實(shí)體。
張三豐:我希望你從一開始就有一個(gè)清醒的認(rèn)識(shí):建模是一項(xiàng)無(wú)中生有的、100%的創(chuàng)造性工作,并不存在某種方法或公式 可以讓你從用例或?qū)嶋H物體里推導(dǎo)出領(lǐng)域模型。領(lǐng)域模型是“分析”不出來(lái)的,它是被“設(shè)計(jì)”出來(lái)的。所以,領(lǐng)域模型里會(huì)有一些現(xiàn)實(shí)世界里并不存在的實(shí)體,當(dāng) 然也會(huì)有與現(xiàn)實(shí)世界里的物體同名的實(shí)體,但是它只是表現(xiàn)現(xiàn)實(shí)物體的某個(gè)方面,所以它的職責(zé)也就很可能與現(xiàn)實(shí)物體不同。至于報(bào)表,一般多是取自幾個(gè)實(shí)體中的 數(shù)據(jù),還要進(jìn)行匯總等統(tǒng)計(jì)操作,所以比較適合用來(lái)驗(yàn)證模型,而不是一開的創(chuàng)建模型的工作。
殷六俠:唉,師傅,您越說我就越糊涂,恐怕弟子是要辜負(fù)師傅的重托了……
張三豐:別急,其實(shí)建模還是有一些實(shí)用技巧的,待為師傳你建模心法。呃,今天時(shí)候不早了,明天再說吧。拜拜
殷六俠:師傅晚安。
殷六俠回到客棧,周圍突然一下子變黑了,屏幕上出現(xiàn)一行小字:“正在存盤……”
第二天的QQ聊天記錄
殷六俠:師傅早。
張三豐:早。昨天說到哪了?對(duì),建模心法。先傳你建模心法1。
建模心法1 尋找線索實(shí)體。
殷六俠:什么叫線索實(shí)體?
張三豐:就是生命周期恰好貫穿整個(gè)業(yè)務(wù)流程的那個(gè)實(shí)體。這個(gè)實(shí)體就像一條線,將整個(gè)業(yè)務(wù)流程中的其它實(shí)體串起來(lái),形成星型的結(jié)構(gòu)。
殷六俠:我明白了,例如一個(gè)企業(yè)的銷售業(yè)務(wù)就是簽訂合同、執(zhí)行合同,那么“合同”就是這樣的一個(gè)線索實(shí)體。
張三豐:沒錯(cuò)。
殷六俠:讓我想想,對(duì)于住院管理來(lái)說,這個(gè)線索實(shí)體的生命周期應(yīng)該在患者入院時(shí)開始,患者出院時(shí)結(jié)束。“病歷本”符合這一條件,不過讓其它的實(shí)體都關(guān)聯(lián)“病歷本”似乎不大自然。由于患者可能多次住院,所以患者這個(gè)實(shí)體的生命周期顯然過長(zhǎng)而不適合作為線索實(shí)體。
張三豐:很好。
殷六俠:這個(gè)線索實(shí)體可以定義為“患者的一次住院”。嗯……可以叫“住院履歷”,或者干脆叫“住院記錄”好了。
張三豐:這個(gè)名字還算湊合吧。起一個(gè)好名字還是很難的,以后有空多去武當(dāng)山下的釀名齋坐坐。
殷六俠:是,師傅。有了這個(gè)線索實(shí)體類,其它的幾個(gè)相關(guān)的實(shí)體也很自然地產(chǎn)生了。
張三豐:看上去挺不錯(cuò)的,不過我要提醒你,領(lǐng)域模型是要能滿足所有用例的所有場(chǎng)景的,這個(gè)模型里沒有包括費(fèi)用相關(guān)的實(shí)體呀。
殷六俠:是啊,直覺上費(fèi)用的處理挺復(fù)雜的。
張三豐:你的直覺很正確?,F(xiàn)在為師傳你建模心法2。
建模心法2 尋找相似場(chǎng)景。
張三豐:如果幾個(gè)用例中都包含相似的場(chǎng)景,例如“計(jì)費(fèi)”,就可以把這些相似的場(chǎng)景抽取出來(lái)成為一個(gè)單獨(dú)的用例,再讓其 它用例包含(include)這個(gè)被抽取出來(lái)的用例,不過這不是必須的。最重要的是你要認(rèn)識(shí)到尋找相似場(chǎng)景的意義。越多的用例包含這個(gè)相似場(chǎng)景,就說明這 個(gè)場(chǎng)景的業(yè)務(wù)越復(fù)雜,設(shè)計(jì)不當(dāng)?shù)目赡苄栽礁?#xff1b;將來(lái)重構(gòu)的成本也越大。換句話說就是風(fēng)險(xiǎn)越發(fā)的高,所以更需要你加倍仔細(xì)、小心地處理。
殷六俠:您是說我們要設(shè)計(jì)一個(gè)實(shí)體-關(guān)系結(jié)構(gòu),可以滿足所有的相似場(chǎng)景?感覺好難的說。
張三豐:沒錯(cuò),有時(shí)會(huì)感覺太復(fù)雜而無(wú)法把握,這時(shí)可以試試建模心法3。
建模心法3 使用示例場(chǎng)景(Sample Scenario),尋找一致性。
張三豐:示例場(chǎng)景是一組(最好是連續(xù)的)模擬真實(shí)業(yè)務(wù)的場(chǎng)景。例如和費(fèi)用相關(guān)的示例場(chǎng)景為:
場(chǎng)景一:患者入院登記。交預(yù)繳金200元。申請(qǐng)獲得500元擔(dān)保金。為醫(yī)?;颊?#xff0c;醫(yī)保卡內(nèi)有1000元。
場(chǎng)景二:第一天消費(fèi)感冒通一盒(50元)、抽血一次(30元)、床位費(fèi)(100元)
場(chǎng)景三:經(jīng)申請(qǐng),擔(dān)保金額度升為1000元。另,護(hù)士重新讀取了醫(yī)???#xff0c;醫(yī)??ɡ锏挠囝~是2000元。
場(chǎng)景三:鑲金牙(1000元,走現(xiàn)金帳戶),擔(dān)保金+賬戶余額=100元小于最低預(yù)繳金額(200元,系統(tǒng)參數(shù)),要求續(xù)費(fèi)
場(chǎng)景四:續(xù)交現(xiàn)金預(yù)繳金2000元。
場(chǎng)景五:護(hù)士刷醫(yī)??ɡU費(fèi)。
????? 最好與領(lǐng)域?qū)<夜餐谱魇纠龍?chǎng)景。要涵蓋所有可能的情況,同時(shí)注意不要包含現(xiàn)實(shí)業(yè)務(wù)中不存在的情況以避免不必要的復(fù)雜性。如果領(lǐng)域?qū)<抑赋瞿撤N情況是不存 在的,應(yīng)該進(jìn)一步追問其原因。原因可能是“目前為止還從未出現(xiàn)過這種情況,雖然理論上是合理的”,“這種情況是違反法律或行規(guī)的”,“這么做將傷害公司或 客戶的利益”,“為了方便某個(gè)部門或某類員工的工作”、“也許這么做會(huì)更合算,但是我們領(lǐng)導(dǎo)偏偏就要求要按現(xiàn)在的做法去做”等等。無(wú)論是何種原因,都可能 成為未來(lái)的變更點(diǎn)。雖然目前的設(shè)計(jì)不必理會(huì)這些不可能情況,但是可以思考一下將來(lái)發(fā)生變更時(shí)如何修改現(xiàn)有設(shè)計(jì),以此為契機(jī)很可能會(huì)發(fā)現(xiàn)更為簡(jiǎn)單且富有彈性 的設(shè)計(jì)。
????? 上面的示例場(chǎng)景是不完全的,因?yàn)闆]有涉及退費(fèi)相關(guān)的場(chǎng)景(抱歉限于篇幅沒有給出退費(fèi)相關(guān)的用例),就以上面的5個(gè)示例場(chǎng)景,該如何設(shè)計(jì)領(lǐng)域模型呢?
????? 可以注意到示例場(chǎng)景中存在兩類金額:預(yù)繳金和擔(dān)保金。執(zhí)行某醫(yī)囑時(shí)可能從預(yù)繳金中扣錢,但是也可能從醫(yī)??ㄖ锌坼X。出于需要為患者打印每日費(fèi)用明細(xì)(抱歉限于篇幅沒有給出這個(gè)用例)和退費(fèi),需要記錄每筆費(fèi)用,這讓你想到了什么?
殷六俠:這讓我想到可以試試賬戶+變更記錄這個(gè)模式(關(guān)于常用的分析模式,我打算以后再寫幾篇來(lái)專門介紹),讓我仔細(xì)想想……
1小時(shí)之后
殷六俠:我想到醫(yī)保卡余額與擔(dān)保金在概念上很相似,這樣就可以一致地處理醫(yī)??ㄙ~戶和現(xiàn)金賬戶了。
殷六俠:領(lǐng)域模型變成這樣:
殷六俠:示例場(chǎng)景確實(shí)給了我不少感性認(rèn)識(shí)。
張三豐:隨著OOA&D的流行,人們普遍認(rèn)同一開始建模的時(shí)候不應(yīng)考慮實(shí)現(xiàn)細(xì)節(jié),而應(yīng)把注意力集中在對(duì)領(lǐng)域的 深刻理解上。領(lǐng)域模型里的對(duì)象結(jié)構(gòu)與實(shí)際的數(shù)據(jù)庫(kù)表結(jié)構(gòu)可以有很大的不同;實(shí)體間的關(guān)聯(lián)也不一定非得實(shí)現(xiàn)為外鍵關(guān)聯(lián)……不過請(qǐng)不要把可以忽略實(shí)現(xiàn)細(xì)節(jié)等同 于可以忽略細(xì)節(jié)領(lǐng)域知識(shí)。正所謂“細(xì)節(jié)就是魔鬼”,醉心于抽象和一致性,而沒有把同等甚至更多的精力投入到發(fā)現(xiàn)不一致的細(xì)微之處上,實(shí)在是一種很危險(xiǎn)的做 法。所謂“具而不抽則罔,抽而不具則殆”,讓思維在抽象和具體之間來(lái)回移動(dòng)才更有效。示例場(chǎng)景還給了你一個(gè)“橫切”用例的機(jī)會(huì),可以讓你對(duì)業(yè)務(wù)有一個(gè)更加 立體的認(rèn)識(shí)。
殷六俠:制作示例場(chǎng)景還是一個(gè)發(fā)現(xiàn)遺漏用例和提出尖銳問題的好機(jī)會(huì)。例如剛剛我就很自然地想到“擔(dān)保金只是對(duì)現(xiàn)金賬戶 來(lái)說的么?還是對(duì)現(xiàn)金賬戶和醫(yī)保賬戶同時(shí)有效?例如當(dāng)現(xiàn)金賬戶和醫(yī)??ɡ锩娴腻X都用光了,而擔(dān)保金為3000元時(shí),這時(shí)計(jì)費(fèi)只能走現(xiàn)金賬戶還是也可以走醫(yī) 保賬戶呢?”
小結(jié) USM三視圖法
????? 運(yùn)用本文介紹的USM(用例-示例場(chǎng)景-領(lǐng)域模型)三視圖法,可令 Modeler 從不同視角觀察企業(yè)業(yè)務(wù),讓思維在抽象和具體之間來(lái)回移動(dòng),互相促進(jìn)、完善,發(fā)現(xiàn)未曾注意的細(xì)節(jié),找出概念上的一致性,不斷加深對(duì)領(lǐng)域的理解。希望USM 三視圖法成為虛空中的一塊踏腳石,幫助 Modeler 邁出建模第一步。
?
參考文獻(xiàn)
Craig Larman,UML和模式應(yīng)用。機(jī)械工業(yè)出版社,2004.
Martin Fowler 著,徐家福 譯,UML 精粹(第2版)標(biāo)準(zhǔn)對(duì)象建模語(yǔ)言簡(jiǎn)明指南。清華大學(xué)出版社,2002。
Eric Evans, 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(影印版)。人民郵電出版社,2007。
Martin Fowler, 分析模式(影印版)。中國(guó)電力出版社,2003.
RicCC,分析模式讀書筆記。博客園,2008.
轉(zhuǎn)載于:https://www.cnblogs.com/jiushini/archive/2012/05/27/2520522.html
總結(jié)
以上是生活随笔為你收集整理的建模心法(2)——迈出建模第一步的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【原创】SVM小结
- 下一篇: 怎么用计算机拨号手机,教你如何用电脑连接