色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain Driven Design)參考架構(gòu)詳解

  1. 架構(gòu)概述

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain Driven Design)有一個(gè)官方的sample工程,名為DDDSample,官網(wǎng):http://dddsample.sourceforge.NET/,該工程給出了一種實(shí)踐領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的參考架構(gòu),本文將對(duì)此該架構(gòu)進(jìn)行簡(jiǎn)單介紹,并就一些重要問(wèn)題進(jìn)行討論。

  該架構(gòu)分成了Interfaces、Applications和Domain三層以及包含各類(lèi)基礎(chǔ)設(shè)施的Infrastructure。下圖簡(jiǎn)略描述了它們之間的關(guān)系:

  圖1 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)風(fēng)格的架構(gòu)草圖(來(lái)自于DDDSample官網(wǎng))

  下圖是詳細(xì)架構(gòu):

  圖2 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)參考架構(gòu)

  作為參照,下圖展示了傳統(tǒng)TransactionScript風(fēng)格的架構(gòu),可以看出,兩者的差異并不是太大(對(duì)于Fa?ade來(lái)說(shuō),它是一種可選設(shè)施,如果系統(tǒng)架構(gòu)中省略Fa?ade,則DTO與領(lǐng)域?qū)ο蟮幕Q工作可在service中進(jìn)行),這也從則面說(shuō)明推行領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的關(guān)鍵并不在架構(gòu)上,而在于整個(gè)團(tuán)隊(duì)在分析、設(shè)計(jì)和開(kāi)發(fā)上沒(méi)有自始至終地以領(lǐng)域模型為核心開(kāi)展工作,以面向?qū)ο蟮乃枷脒M(jìn)行設(shè)計(jì)和編程。

  Transaction Script風(fēng)格的架構(gòu)具有明顯的“數(shù)據(jù)”與“操作”分離的特征,其和領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)風(fēng)格的架構(gòu)在兩個(gè)類(lèi)組件上有質(zhì)的區(qū)別,一個(gè)是領(lǐng)域?qū)ο螅粋€(gè)是Service。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的架構(gòu)核心目標(biāo)是要?jiǎng)?chuàng)建一個(gè)富領(lǐng)域模型,其典型特征是它的領(lǐng)域?qū)ο缶哂胸S富的業(yè)務(wù)方法用以處理業(yè)務(wù)邏輯,而Transaction Script風(fēng)格的領(lǐng)域?qū)ο髣t僅僅是數(shù)據(jù)的載體,沒(méi)有業(yè)務(wù)方法,這種領(lǐng)域也被稱作“貧血的領(lǐng)域?qū)ο?rdquo;(Anemic Domain Objects)。在Service方面,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的架構(gòu)里Service是非常“薄“的一層,其并不負(fù)責(zé)處理業(yè)務(wù)邏輯,而在TransactionScript風(fēng)格的架構(gòu)里,Service是處理業(yè)務(wù)邏輯的主要場(chǎng)所,因而往往非常厚重。

  圖3. 數(shù)據(jù)與操作分離的Transaction Script風(fēng)格的架構(gòu)

  2. 架構(gòu)詳解

  2. 1 Interfaces-接口層

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)對(duì)Interfaces的定位是:

  Thislayer holds everything that interacts with other systems, such as web services,RMI interfaces or web applications, and batch processing frontends. It handlesinterpretation, validation and translation of incoming data. It also handlesserialization of outgoing data, such as HTML or XML across HTTP to web browsersor web service clients, or DTO classes and distributed facade interfaces forremote Java clients.

  該層包含與其他系統(tǒng)進(jìn)行交互的接口與通信設(shè)施,在多數(shù)應(yīng)用里,該層可能提供包括Web Services、RMI或Rest等在內(nèi)的一種或多種通信接口。該層主要由Facade、DTO和Assembler三類(lèi)組件構(gòu)成,三類(lèi)組件均是典型的J2EE模式,以下是對(duì)三類(lèi)組件的具體介紹:

  2.1.1 DTO

  DTO- DataTransfer Object(數(shù)據(jù)傳輸對(duì)象),也常被稱作VO-Value Object(值對(duì)象)。基于面向?qū)ο蠹夹g(shù)設(shè)計(jì)的領(lǐng)域?qū)ο螅赐ǔKf(shuō)的“實(shí)體”)都是細(xì)粒度的,將細(xì)粒度的領(lǐng)域?qū)ο笾苯觽鬟f到遠(yuǎn)程調(diào)用端需要進(jìn)行多次網(wǎng)絡(luò)通信,DTO在設(shè)計(jì)之初的主要考量是以粗粒度的數(shù)據(jù)結(jié)構(gòu)減少網(wǎng)絡(luò)通信并簡(jiǎn)化調(diào)用接口。以下羅列了DTO的多項(xiàng)作用:

  • Reduces NETwork traffic
  • Simplifies remote object and remote interface
  • Transfers more data in fewer remote calls
  • Reduces code duplication
  • Introduces stale transfer objects
  • Increases complexity due to synchronization and version control

  圖4. DTO應(yīng)用時(shí)序圖(基于《Core J2EE Patterns》插圖進(jìn)行了修改)

  值得一提的是,DTO對(duì)實(shí)現(xiàn)一個(gè)獨(dú)立封閉的領(lǐng)域模型具有積極的作用,特別是當(dāng)系統(tǒng)使用了某些具有自動(dòng)臟數(shù)據(jù)檢查(automatic dirty checking)機(jī)制的ORM框架時(shí),DTO的優(yōu)勢(shì)就更加明顯,否則就會(huì)存在領(lǐng)域?qū)ο笤谀P蛯右酝獗灰馔庑薷牟⒆詣?dòng)持久化到數(shù)據(jù)庫(kù)中的風(fēng)險(xiǎn)或者是像Hibernate那樣的框架因未開(kāi)啟OpenSessionInView (注:開(kāi)啟OpenSessionInView有副作用,一般認(rèn)為OpenSessionInView不是一種好的實(shí)踐)而導(dǎo)致Lazy Loading出現(xiàn)問(wèn)題。

  關(guān)于DTO具體的設(shè)計(jì)用意和應(yīng)用場(chǎng)景可參考如下資源:

  • 《Core J2EE? Patterns: Best Practices and Design Strategies, SecondEdition》
  • 《Patterns of Enterprise ApplicationArchitecture》

  2.1.2 Assembler

  在引入DTO后,DTO與領(lǐng)域?qū)ο笾g的相互轉(zhuǎn)換工作多由Assembler承擔(dān),因此Assembler幾乎總是同DTO一起出現(xiàn)。也有一些系統(tǒng)使用反射機(jī)制自動(dòng)實(shí)現(xiàn)DTO與領(lǐng)域?qū)ο笾g的相互轉(zhuǎn)換,Appache的Commons BeanUtils就提供了類(lèi)似的功能。應(yīng)該說(shuō)這兩種實(shí)現(xiàn)各有利弊,使用Assembler進(jìn)行對(duì)象數(shù)據(jù)交換更為安全與可控,并且接受編譯期檢查,但是代碼量明顯偏多。使用反射機(jī)制自動(dòng)進(jìn)行象數(shù)據(jù)交換雖然代碼量很少,但卻是非常脆弱的,一旦對(duì)象屬性名發(fā)生了變化,數(shù)據(jù)交互就會(huì)失敗,并且很難追蹤發(fā)現(xiàn)。總體來(lái)說(shuō),Assembler更為直白和穩(wěn)妥。

  圖5. Assebler應(yīng)用類(lèi)圖(基于《Core J2EE Patterns》插圖進(jìn)行了修改)

  關(guān)于Assembler具體的設(shè)計(jì)用意和應(yīng)用場(chǎng)景可參考如下資源:

  • 《Core J2EE? Patterns: Best Practices and Design Strategies, SecondEdition》
  • 《Patterns of Enterprise ApplicationArchitecture》

  2.1.3 Facade

  作為一種設(shè)計(jì)模式同時(shí)也是Interfaces層內(nèi)的一類(lèi)組件,F(xiàn)acade的用意在于為遠(yuǎn)程客戶端提供粗粒度的調(diào)用接口。Facade本身不處理任何的業(yè)務(wù)邏輯,它的主要工作就是將一個(gè)用戶請(qǐng)求委派給一個(gè)或多個(gè)Service進(jìn)行處理,同時(shí)借助Assembler將Service傳入或傳出的領(lǐng)域?qū)ο筠D(zhuǎn)化為DTO進(jìn)行傳輸。以下羅列了Facade的多項(xiàng)作用:

  • Introduces a layer that provides services to remote clients
  • Exposes a uniform coarse-grained interface
  • Reduces coupling between the tiers
  • Promotes layering, increases flexibility and maintainability
  • Reduces complexity
  • Improves performance, reduces fine-grained remote methods
  • Centralizes security management
  • Centralizes transaction control
  • Exposes fewer remote interfaces to clients

  實(shí)踐Facade的過(guò)程中最難把握的問(wèn)題就是Facade的粒度問(wèn)題。傳統(tǒng)的Service均以實(shí)體為單位進(jìn)行組織,而Facade應(yīng)該具有更粗粒度的組織依據(jù),較為合適的粒度依據(jù)有:一個(gè)高度內(nèi)聚的模塊一個(gè)Facade,或者是一個(gè)“聚合”(特指領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中的聚合)一個(gè)Facade.

  圖6. Facade應(yīng)用類(lèi)圖(基于《Core J2EE Patterns》插圖進(jìn)行了修改)

  圖7. Facade應(yīng)用時(shí)序圖(基于《Core J2EE Patterns》插圖進(jìn)行了修改)

  關(guān)于Assembler具體的設(shè)計(jì)用意和應(yīng)用場(chǎng)景可參考如下資源:

  • 《Core J2EE? Patterns: Best Practices and Design Strategies, SecondEdition》
  • 《Patterns of Enterprise ApplicationArchitecture》
  • 《Design Patterns: Elementsof Reusable Object-Oriented Software》

  2.2 Application-應(yīng)用

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)對(duì)Application的定位是:

  Theapplication layer is responsible for driving the workflow of the application,matching the use cases at hand. These operations are interface-independent andcan be both synchronous or message-driven. This layer is well suited forspanning transactions, high-level logging and security. The application layeris thin in terms of domain logic - it merely coordinates the domain layerobjects to perform the actual work.

  Application層中主要組件就是Service,在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的架構(gòu)里,Service的組織粒度和接口設(shè)計(jì)依據(jù)與傳統(tǒng)Transaction Script風(fēng)格的Service是一致的,但是兩者的實(shí)現(xiàn)卻有著質(zhì)的區(qū)別。TransactionScript風(fēng)格的Service是實(shí)現(xiàn)業(yè)務(wù)邏輯的主要場(chǎng)所,因此往往非常厚重。而在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的架構(gòu)里,Application是非常“薄”的一層,所有的Service只負(fù)責(zé)協(xié)調(diào)并委派業(yè)務(wù)邏輯給領(lǐng)域?qū)ο筮M(jìn)行處理,其本身并真正實(shí)現(xiàn)業(yè)務(wù)邏輯,絕大部分的業(yè)務(wù)邏輯都由領(lǐng)域?qū)ο蟪休d和實(shí)現(xiàn)了,這是區(qū)別系統(tǒng)是Transaction Script架構(gòu)還是Domain Model架構(gòu)的重要標(biāo)志。

  不管是Transaction Script風(fēng)格還Domain Model風(fēng)格,Service都會(huì)與多種組件進(jìn)行交互,這些組件包括:其他的Service、領(lǐng)域?qū)ο蠛蚏epository 或 DAO。

  圖8. Service應(yīng)用時(shí)序圖(基于《Core J2EE Patterns》插圖進(jìn)行了修改)

  Service的接口是面向用例設(shè)計(jì)的,是控制事務(wù)、安全的適宜場(chǎng)所。如果Facade的某一方法需要調(diào)用兩個(gè)以上的Service方法,需要注意事務(wù)問(wèn)題。

  2.3 Domain-領(lǐng)域?qū)?/strong>

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)對(duì)Domain的定位是:

  Thedomain layer is the heart of the software, and this is where the interestingstuff happens. There is one package per aggregate, and to each aggregatebelongs entities, value objects, domain events, a repository interface andsometimes factories.

  Thecore of the business logic belongs in here. The structure and naming ofaggregates, classes and methods in the domain layer should follow theubiquitous language, and you should be able to explain to a domain expert howthis part of the software works by drawing a few simple diagrams and using theactual class and method names of the source code.

  Domain層是整個(gè)系統(tǒng)的核心層,該層維護(hù)一個(gè)使用面向?qū)ο蠹夹g(shù)實(shí)現(xiàn)的領(lǐng)域模型,幾乎全部的業(yè)務(wù)邏輯會(huì)在該層實(shí)現(xiàn)。Domain層包含Entity(實(shí)體)、ValueObject(值對(duì)象)、Domain Event(領(lǐng)域事件)和Repository(倉(cāng)儲(chǔ))等多種重要的領(lǐng)域組件。

  2.4 Infrastructure-基礎(chǔ)設(shè)施層

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)對(duì)Infrastructure的定位是:

  Inaddition to the three vertical layers, there is also the infrastructure. As thethe picture shows, it supports all of the three layers in different ways,facilitating communication between the layers. In simple terms, theinfrastructure consists of everything that exists independently of ourapplication: external libraries, database engine, application server, messagingbackend and so on.

  Also,we consider code and configuration files that glues the other layers to theinfrastructure as part of the infrastructure layer. Looking for example at thepersistence ASPect, the database schema definition, Hibernate configuration andmapping files and implementations of the repository interfaces are part of theinfrastructure layer.

  Whileit can be tricky to give a solid definition of what kind of code belongs to theinfrastructure layer for any given situation, it should be possible tocompletely stub out the infrastructure in pure Java unit/scenario tests andstill be able to use the domain layer and possibly the application layer towork out the core business problems.

  作為基礎(chǔ)設(shè)施層,Infrastructure為Interfaces、Application和Domain三層提供支撐。所有與具體平臺(tái)、框架相關(guān)的實(shí)現(xiàn)會(huì)在Infrastructure中提供,避免三層特別是Domain層摻雜進(jìn)這些實(shí)現(xiàn),從而“污染”領(lǐng)域模型。Infrastructure中最常見(jiàn)的一類(lèi)設(shè)施是對(duì)象持久化的具體實(shí)現(xiàn)。

  3. 關(guān)于架構(gòu)的一些討論

  3.1 架構(gòu)并不能保證領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的貫徹與執(zhí)行

  雖然一個(gè)合適的架構(gòu)對(duì)于實(shí)施領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)是大有必要的,但只依靠架構(gòu)是不能保證領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的貫徹與執(zhí)行的。實(shí)際上,在這個(gè)參考架構(gòu)上使用Transaction Script的方式進(jìn)行開(kāi)法幾乎沒(méi)有任何問(wèn)題,只要開(kāi)發(fā)人員將領(lǐng)域?qū)ο笞兂?ldquo;貧血”的“數(shù)據(jù)載體”對(duì)待,在service里實(shí)現(xiàn)業(yè)務(wù)邏輯,那么該參考架構(gòu)將成為純粹的TransactionScript方式。當(dāng)然反過(guò)來(lái)看,這也體現(xiàn)了這一架構(gòu)的靈活性。確保領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的貫徹與執(zhí)行需要整個(gè)團(tuán)隊(duì)在分析、設(shè)計(jì)和開(kāi)發(fā)上沒(méi)有自始至終地以領(lǐng)域模型為核心開(kāi)展工作,以面向?qū)ο蟮乃枷脒M(jìn)行設(shè)計(jì)和編程,才能保證實(shí)現(xiàn)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)。

  3.2 Facade是否是必須的?

  盡管在架構(gòu)中對(duì)Facade的定義非常清晰,但在實(shí)踐中我發(fā)現(xiàn)Facade并不是一個(gè)容易拿捏的東西。主要問(wèn)題在于其與Service之間的有太多的重疊與相似之處。我們注意到Service是接口是面向一個(gè)use case的,因此事務(wù)也是追加在Service這一層上,于是對(duì)于Facade而言,99%的情況是,它只是把某個(gè)Service的某個(gè)方法再包裹一下而已,如果把領(lǐng)域?qū)ο蠛虳TO的互轉(zhuǎn)換工作移至Service中進(jìn)行,那么Facade將徹底變成空殼,而關(guān)鍵的是:如果Service的接口設(shè)計(jì)是面向和user case的,那么,毫無(wú)疑問(wèn),Service接口的傳入傳出參數(shù)也都應(yīng)該是DTO,而這一點(diǎn)也在《Core J2EE Patterns: Best Practices and Design Strategies, SecondEdition》和《Patterns of Enterprise ApplicationArchitecture》兩書(shū)的示例代碼中完全印證了。那么,從更為務(wù)實(shí)角度出發(fā),F(xiàn)acade并非是一種必須的組件。

it知識(shí)庫(kù)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain Driven Design)參考架構(gòu)詳解,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 周口市| 饶平县| 德安县| 鄢陵县| 如东县| 石棉县| 丰台区| 六盘水市| 正宁县| 泸定县| 西畴县| 长武县| 西盟| 建水县| 崇义县| 潍坊市| 桃江县| 宁陵县| 石泉县| 阿克苏市| 定结县| 泸溪县| 永寿县| 金华市| 淄博市| 肇源县| 南康市| 宁阳县| 湟源县| 车险| 荃湾区| 海晏县| 陵川县| 同仁县| 邵阳县| 张家口市| 兴隆县| 萨迦县| 辉南县| 大港区| 卫辉市|