在開始以前,我想咱們有必要先了解如下DDD的主要參與者。由於畢竟語言是人說的嗎,就像咱們面向對象編程同樣,那通用語言面向的是?
DDD的主要參與者:領域專家+開發人員
領域專家:精通業務的任何人。
開發人員:開發+測試。
領域專家擅長某個領域的知識,專一於交付的業務價值。
開發人員則注重於技術實現。
開發人員老是想着類、接口、方法、設計模式、架構等。以面向對象的編程思想進行思考,思考如何進行抽象、封裝、繼承、多態等。而領域專家對軟件中的框架、持久化、數據庫等沒有概念,而這也就致使了他們之間交流的困難性。數據庫
那怎麼解決交流障礙這個問題呢?編程
拋開DDD而言,單從字面意思來理解,咱們首先確定先聯想到做爲世界使用最多的語言--英語。
英語之因此能成爲通用語言,我想無非是如下幾方面:設計模式
簡單易學架構
使用率高框架
國際通用ide
那DDD中通用語言又是怎樣呢?
首先它也一樣要擁有【簡單】的特性,這樣才便於理解和傳播。
其次,它也要有【通用】、【使用率高】的特性,由於只有在軟件開發的過程當中,團隊範圍內全部的參與人員普遍使用,才能準確傳遞業務規則。測試
通用語言是團隊交流的基礎上創建起來的,代碼則是基於通用語言來進行業務表達的。spa
項目經理安排了一項任務給我:
聖傑這個補丁處理下【可銷控制】這個需求。
聽後,真是一臉懵逼,【可銷控制】是什麼鬼?設計
這明顯是專業術語,我不懂的專業術語。
按照DDD對通用語言的定義,【可銷控制】就不算通用語言。
由於只有領域專家知道它的含義,開發人員一臉茫然。code
但通用語言是領域專家和開發人員一塊兒建立的,因此咱們開個需求會議,來梳理下專業術語背後的含義。
可銷控制的應用場景是:
在ERP中,在作單時對銷售員負責的客戶進行範圍控制。好比,A客戶是銷售員小李發展過來的,小李但願僅能本身負責對A客戶的業務。
這麼一解釋,是否是明白很多了。可是不是還有幾點疑惑?
可銷範圍如何配置?
作什麼單據時進行可銷範圍控制?
如何進行可銷控制?
可銷控制需不須要參數控制?
通過討論,得出如下結論:
提供專門的【銷售員-客戶可銷控制】界面進行銷售員-客戶映射數據配置。
作銷售訂單單據時進行可銷範圍控制
在錄入銷售員後,作單員在選擇客戶列表時,客戶列表中僅顯示可銷範圍配置的客戶數據。
提供【銷售員-客戶可銷範圍控制】系統參數,勾選後才進行可銷範圍控制。
好了,這下需求理解個七八九了。
原來可銷控制就是銷售員-客戶銷售範圍控制。
我們用一句話來精簡下這個需求:
可銷控制是指銷售員所負責客戶的範圍控制,當勾選了【銷售員-客戶可銷控制】參數後,在作銷售訂單錄入客戶數據時,客戶列表僅能選擇到在【可銷控制】列表中爲該銷售員配置的客戶。
通過這麼一說明,咱們是否是已經理清了【可銷控制】這個需求點。
那這種經過團隊交流達成共識的可以簡單清晰準確傳遞業務規則的語言(能夠是文字、圖片等)便可稱爲通用語言。
就像上面所說的那樣,通用語言的最大價值是解決了交流障礙問題,使領域專家和開發人員可以協同合做,從而可以確保業務需求的正確表達。
另外,基於通用語言,開發人員可以開發出可讀性更好的代碼,從而將業務需求準確轉化爲代碼設計。達到DDD的目標代碼即設計,設計即代碼。通俗的講,也就是開發人員寫的代碼領域專家也能看懂。
既然開發人員也要基於通用語言進行代碼開發,那代碼如何體現通用語言呢?
在《實現領域驅動設計》書中有一個簡單的例子(P238),咱們一塊兒來看一下:
系統必須對User進行認證,而且只有當Tenant(租戶)處於激活狀態時才能對User進行認證。
上面這個用例就是基於通用語言的用例,簡單清楚的說明了業務規則。
咱們先看第一種代碼實現:
bool anthentic = false; User user = _userRepository().FindUserByTenantIdAndUserName(tenantId, userName);if(user!=null) { authentic = user.IsAuthentic(password); }return authentic;
這段代碼徹底不能反應通用語言,主要存在如下問題:
這段代碼先查找user,再對user進行密碼匹配來完成認證。其中user.IsAuthentic(password);
表示的是「用戶是否被認證」的意思,而沒有表達出「認證」這個過程,即「對用戶進行認證」。
未體現「檢查Tenant是否處於激活狀態」這個前提條件。
知道問題後,咱們能夠講代碼略作改動:
bool anthentic = false; Tenant tenant = _tenantRepository.FindTenantById(tenantId);//檢查租戶是否激活if(tenant!=null&&tenant.IsActive){ User user = _userRepository.FindUserByTenantIdAndUserName(tenantId, userName);if(user!=null) { authentic = tenant.Authenticate(user, password);//租戶對用戶進行認證} }return authentic;
以上代碼雖然也不是最終結果,但至少對通用語言進行了體現。通讀代碼,就能明白業務用例,體現代碼即設計這一思想。
閱罷此文,若是您以爲本文不錯並有所收穫,請【打賞】或【推薦】,也可【評論】留下您的問題或建議與我交流。
你的支持是我不斷創做和分享的不竭動力!
做者:『聖傑』
出處:http://www.cnblogs.com/sheng-jie/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接,不然保留追究法律責任的權利。
分類: