業務建模是OOAD的重要組成部分,簡單的說,業務建模就對業務領域問題進行結構化的描述。這個描述將會直接指導最終生成的軟件,業務模型是否具有擴展性,業務模型是否能夠正確的反映需求,都將影響最終軟件的質量。
1.1 為什么要業務建模?
我們把業務建模這個概念放在了最后的部分,因為面向對象是業務建模的基礎。面向對象是一種用計算機語言模擬現實生活的技術。而傳統的語言是基于時序的,是計算機觀點的語言,和人們熟悉的社會觀點是不同的。在軟件發展初期時,這并不是什么很大的問題,但是當軟件規模越來越大,變化的速度越來越快的時候。人們發現兩種觀念有了沖突。例如,訂單這個對象是人類社會的一個普遍的商業名詞,它是相當穩定的。所不同的只是處理規則有所不同,但在傳統的語言中,訂單的名詞并不是關心的重點,關心的重點反而放在了訂單的處理時序上。偏偏這部分的處理是不穩定的,所以就引發了變化的問題。而面向對象采用現實世界系統的思考方式,側重于建立訂單這個類型,并構造訂單類型的體系,然后再建立規則。所以,他和現實世界的變化頻度是基本一致,變化起來也就比較容易。
我們之前曾多次討論了面向對象的抽象。我們知道,面向對象用于描述現實世界,他的抽象級別還太低了。所以,后來有了組件技術。組件技術提倡松耦合、粗粒度的構建方式,但是他在本質上和面向對象并沒有什么太大的差異。而業務建模的關鍵,就是如何利用面向對象技術來描述現實世界。
1. 2 業務建模和數據庫建模
很多人都經歷過基于數據的應用,在需求分析完畢后,立刻建立數據模型,基于數據模型構建應用。這是這種應用的典型做法。利用先進的工具,能夠達到很高的開發速度,所以這種方法在CS方式的軟件中被大量采用。這種方法的基本思想是使用數據庫來表示業務模型。但是我們需要深入的來思考這個問題,是不是數據庫能夠完全勝任這一點呢?我們就最廣泛使用的關系型數據庫來進行討論。
我們知道,關系型數據庫的基本原理是集合論。通過定義二維表和使用笛卡兒乘積定義二維表之間的關系來完成設計。這和我們現實生活有一定的類似之處,這是很自然的一件事情,因為數學本身就來源于生活,而軟件的基礎理論是數學。對于數據來說,它本身并沒有很多意義,你能夠說明下面這個字符串的意義嗎?
|
答案是不能,但是通過數據庫的表名稱和表字段的定義,我們可以大致推算出他的應用范圍:
|
我們知道,這個字符串表示了客戶的中文名稱。但是遺憾的是,這種的定義仍然不夠精確,應該承認,它有用,但是意義并不大,對業務沒什么幫助。真正對業務有幫助的描述應該是:
|
這些事情是數據庫沒有辦法做的。當然,現在數據庫技術的發展一日千里,很多數據庫都用不同的技術來幫助客戶在數據庫上進行業務規則的處理。但是數據庫不擅長處理的東西,并沒有必要強制在數據庫上實現。這些事情,應該由面向對象來進行處理。因為面向對象是數據和操作的完美結合,但是面向對象有一個缺陷,就是持久化的能力很低,所以,數據庫仍然是面向對象的最佳合作伙伴。因此,我們有了ORMapping技術,后來又有了JDO的技術。這些都是為了強化面向對象和關系型數據庫之間的溝通而設計的,因為他們兩者的設計理論不同,所以天生存在很大的隔閡,非得借助中間層次的幫助。而在敏捷方法論中,也專門有研究數據庫方面的技術,這表現了數據庫技術的重要程度。
1.3 共性和差異性
業務建模中,尋找、區分不同事物之間的共性和差異性是非常關鍵的。兩個業務實體,之間不可能只有共性,如果那樣的話,那就只會剩下一個業務實體了;反過來,他們之間也不可能只有差異性,世間萬物,皆有關聯。退一萬步說,他們至少都屬于某個組織的業務實體,都是業務實體,這也是他們的共性。在業務模型中進行正確的分析,能夠為之后的面向對象建模打下堅實的基礎。如果這一步做的不好,你會發現,你是在使用面向對象的技術來編寫面向對象過程的代碼。
1. 4 不要把表和業務實體混為一談
對于業務建模而言,業務實體是非常重要的。幾乎所有的業務模型,都表現為不同業務實體之間的某種協作關系。Jill Nicola在他的業務對象建模和協作模式一文中,提出了4種的協作類型,并演化出12種協作模式。應該說,他的用意,是對業務模型進行分類,其目標和GOF的設計模式一書是類似的。但是業務模型面對著的,是大千世界中的各種現象,要將它們歸類整理,談何容易。所以,Jill Nicola也僅僅是只能夠提出一個思路,但這對業務建模者來說,是很有價值的。
很多開發人員容易把表和業務實體混起來,但它們之間并沒有什么聯系。正如上文討論業務建模和數據庫建模的關系一樣,數據庫只是實現業務模型持久化特性的一種手段。把業務實體一對一映射到表,有時候是對的,有時候則不對。業務實體的設計一定是從需求開始,到領域模型,而表設計是基于數據庫的處理原則。一個訂單實體,在數據庫中可能會有兩張表,一張是訂單、一章是訂單子目。很多時候,業務實體的粒度要大于表,但也不一定,例如在ORMapping中,就常常把一個繼承樹映射到單個表中。所以它們兩者之間沒有必然的聯系。在業務建模時,就單純的考慮業務實體的設計,在數據庫建模時,就單純的考慮表設計,不要混淆兩者。
1. 5 警惕CRUD類型的設計
這個問題產生的本質是數據庫設計和業務模型設計的沖突。從數據庫的觀點來看,任何一種業務都不外乎新增記錄、修改記錄、刪除記錄、查詢記錄。所以象PowerBuilder那樣的工具,能夠憑借優秀的數據窗體的處理能夠里雄踞一方。但是這個觀點是業務建模中十分忌諱的,為什么呢?對任何一項業務來說,對記錄的處理都不是問題的根本。新增一條記錄必定伴隨著一項業務的發生,例如銷售了一件產品,新注冊了一個用戶。這種對用戶來說才是有意義的,用戶并不關心記錄的處理,他們只關心業務問題。所以,當你的業務模型如果充滿了CRUD的設計,這說明你看待業務模型的角度有問題,你仍然停留在從關系數據庫看待業務的層次上。
在軟件開發過程中,這個問題需要引起注意。單純的CRUD方法往往意味著需求沒有被正確地理解,模型可能遺漏了需求。我們想象一個新增訂單記錄的AddOrder方法,一個訂單需要填寫哪些要素?新增訂單時是否需要檢查客戶的信用記錄?是否需要檢查產品的庫存?現實生活中的業務規則很復雜,不可能如此的簡單。那么,現在你可以檢查看看你的系統,是否存在著大量的CRUD設計?
1. 6 盡可能使設計貼近現實世界
這一點并不是絕對的,例如,理論上人的生日是不能夠調整的,但是在軟件的世界中,需要提供修改生日的方法來修正錄入的錯誤。這個問題可以這樣理解。對于軟件系統來說,并不存在創建人這樣的業務模型,這是生命的秘密,不是軟件系統能夠模擬的。真正有意義的業務模型應該是建立檔案,招聘新員工這樣的業務模型,因此修改檔案和修改員工資料都是允許的。
1. 7 顯式接口和隱式接口
想象一個用戶管理模型提供特定客戶的接口,不同的搜索條件使用不同的參數:
|
面向對象能夠很好支持重載特性,因此,這種方式聲明的接口是相當優雅的。對用戶來說,接口是統一的,編譯器能夠提示你使用合適的重載方法,并幫助你檢查類型。問題在于,有一些條件具有相同的參數類型,這就和重載的要求背離了,例如:
|
這個時候,我們就需要改變一下思路,把接口變成顯式定義的:
|
當方法數量比較少的時候,這種顯式接口也很有優勢,因為方法名清晰的表示了其意圖,用戶不需要太多的幫助就能夠使用適當的方法。所以我們這里看到方法名的設計是很重要的,而在團隊內部保持方法名風格的一致同樣是很重要的。
如果獲取客戶這個方法有十幾中的過濾條件,我們發現,顯示接口的方法是有問題的,方法列表太多,用戶難以使用,而選擇邏輯也開始分散,不容易進行擴展。如果說,一個業務方法復雜到了這種程度,我們認為值得多投入一些時間對方法進行改進。我們的思路是把顯式接轉換為隱式接口,并把過濾條件這個概念進行抽象。請注意我們這么做的理由,方法的目的是相同的,都是獲取客戶,但是它們的過濾條件不同,所以我們為了提高抽象性,我們把過濾條件的共性表述出來,這就是過濾條件本身。這就是面向對象的威力,不論是任何的事物,都可以在某個程度上進行抽象。所以我們引入了一個新的過濾對象,CustomerFilter。注意,我并不把它命名為Filter,因為我認為過濾是一個通用的特性,很多的對象都具有這種特性,所以,我希望在條件成熟的時候能夠從CustomerFilter抽取出一個基類出來,能夠將其用于OrderFilter的設計。所以我的命名為將來留有余地,但是我現在并不實現它,因為重構和自動測試技術能夠幫助我很快將Filter實現出來,對這一點我毫不擔心。羅里羅嗦講了這么多,我們來看看最后的方法是什么樣子的:
|
顯示接口和隱式接口在設計中大量存在,你無法下結論說哪一種方法比較好,任何一種方法都有其存在的價值。我們做的是根據情況來進行分析,以決定使用哪一種方法。
那么,過濾器是如何實現的呢?過濾器實現中最重要的是就是過濾規則由誰實現。同樣的,這里的設計同樣是一種權衡。最標準的做法是使用正則表達式,例如"Name Like M*",這樣,過濾器本身只是提供了表達式的敘述,至多再進行語法的檢查而已,接受過濾器的類需要負責實現過濾功能。很多的系統中都提供了類似的操作,因此,設計時可以充分的利用它們。
在Martin Folwer的分析模式一書中,提到了另一種過濾器的設計思路,把過濾規則封裝在過濾器中,由于過濾規則封裝在過濾器中,所以過濾器必須提供一個查詢方法:
|
每一次,提供Customer的類需要向過濾器詢問,這個客戶在過濾器中嗎?過濾器回答。這種做法的好處是提供了更大的靈活性,可以實現非常復雜的過濾規則。但是這種過濾規則會生成復雜的過濾器類,這并不是一個好消息。你可以使用簡單的Case語句,或是子類化等方法來實現過濾策略。
業務建模不存在一個規范,不同人、不同問題,最后的設計結果一定不同。目前大家比較接收的方式是通過模式的形式來記錄、討論一個業務模型。例如,我們考慮銀行的操作人員處理一項業務,這種過程活動就可以使用經典的Participant-Transaction模式來進行描述:
某種角色處理了某個交易,而這個交易和相關的人員都需要記錄下來,這種情況適合采用Participant-Transaction模式來解決。模式針對某個特定環境的特點使之很適合用在業務建模中,業務建模的規范確定之后,還可以給出特定技術平臺下的實現,從而達到規范代碼的目的。
業務建模的組織問題和重用的組織問題極為類似。
最初的模型就保持一個穩定的狀態是不太現實的。所以,把大量的時間花費在完善業務模型上并不是一個好的做法。在項目開始的時候,參與項目的雙方的配合程度低,相互不能夠理解對方的工作,開發方無法理解要處理的問題域,需求方也弄不清楚軟件的最后模樣。水源已經臟了,下游再怎么清理也是有限的。在這種情況下,你認為領域模型能有多大的穩定性?
但是,如果業務模型不能夠快速的確定下來,就會對后續的活動產生影響。所以,在開發過程中,對原先設計和代碼的重構能力是非常重要的。具體的說,就是在需求變化或更加明確的情況下,需要對原先錯誤或不足的設計及代碼進行修改,但在添加或修改原有軟件的同時,能夠保證原先的功能和質量不受影響。所以,為什么迭代的思路不容易貫徹,就是因為后續的變更對之前的架構容易產生影響。而在一個應用中,業務模型往往是整個軟件的核心,所以軟件重構的能力直接表現為業務模型重構的能力。
對于我們來說,業務模型一方面要盡可能的穩定,少變化,另一方面我們又要求業務模型能夠進行快速的變化,以適應需要。所以業務模型設計對過程提出了幾點要求:
4.1 針對業務模型構建自動化測試網
我們說過,業務模型是軟件設計的核心。任何底層的問題都會反饋到業務模型上來,而業務模型和需求非常的接近,因此測試用例的設計難度比較低。我們知道,測試工作最難的就是如何權衡測試工作量和軟件質量的關系,把測試的力量集中在業務模型上,能夠有不錯的效果(這并不是說其它的部分不需要測試,單元測試的主要思路是測試一切可以測試的東西)。但是這種測試也需要付出額外的代價,最典型的是測試環境的建立,由于是業務模型測試,不可能象單元測試那樣容易,所以需要有周全的測試數據和測試計劃。這項工作應該放到業務模型的類設計中,成為進度的一部分。如果是業務模型的關聯性很大,還要從整體上考慮。
4.2 保持設計的統一
業務模型往往是關聯性很強的,而這個趨勢將會越來越明顯。為什么ERP會如此的復雜,就是因為業務關聯性非常的復雜。所以,盡可能在業務建;顒又型度肷俣牧α,保持統一的設計風格。這一點很重要,如果設計思路不統一,會對業務模型產生很大的影響。
4.3 審核
由于業務模型的重要程度,因此建議在每一次迭代初期加強對業務模型的審核。尤其是評估業務模型變化對軟件設計的影響。
4.4 進度估算
同樣的,進度估算同樣可以以業務模型為基礎進行。因為業務模型的粒度適中,所以進度的分配和統計相對比較容易進行。
Design Patterns: Elements of Reusable Object-Oriented Software. Gamma, E. Helm, R. Johnson and J. Vlissides Addison-Wesley 1995. 中文版:《設計模式:可復用面向對象軟件的基礎》,李英軍等譯,機械工業出版社2000 年9 月。
J2EE核心模式 Deepak Alur, John Crupi, Dan Malks 牛志奇等譯,機械工業出版社。
Effective Java Programming Language Guide. Joshua Bloch 2002 中文版:《Effective Java》潘愛民譯,機械工業出版社2003年1月。
[Kel+96b] Wolfgang Keller, Jens Coldewey: Relational Database Access Layers: A Pattern Language, Proceedings PLoP '96, Allerton Park 1996.
[BMR+96] Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal: Pattern-Oriented Software Architecture - A System of Patterns; John Wiley & Sons Ltd., Chichester, England, 1996; ISBN 0-471-95869-7
[Fow97] Martin Fowler: Analysis Patterns- Reusable Object Models; Addison-Wesley Publishing Company, Reading, Massachusetts , 1997; ISBN 0-201-89542-0
[Fowler, roles] Fowler, Martin. Dealing with Roles, http://www.awl.com/cseng/titles/0-201-89542-0/awweb.htm
[Fer00b] E. B. Fernandez and X. Yuan. "Analysis patterns for the order and shipment of a product", Procs. of PloP 2000. http://jerry.cs.uiuc.edu/~plop/plop2k
[Fer00c] E. B. Fernandez. "Stock Manager: an analysis pattern for inventories", Procs. Of PloP 2000. http://jerry.cs.uiuc.edu/~plop/plop2k
Refactoring To Patterns Joshua Kerievsky 2002
關于作者 林星,辰訊軟件工作室項目管理組資深項目經理,有多年項目實施經驗。辰訊軟件工作室致力于先進軟件思想、軟件技術的應用,主要的研究方向在于軟件過程思想、Linux集群技術、OO技術和軟件工廠模式。您可以通過電子郵件 iamlinx@21cn.com 和他聯系。 |
文章來源于領測軟件測試網 http://www.kjueaiud.com/
版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
技術支持和業務聯系:info@testage.com.cn 電話:010-51297073
老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月