天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

DDD & DDDLib在恒拓開(kāi)源的發(fā)展歷程與推廣經(jīng)驗(yàn)

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)的概念源于2004年著名建模專家Eric Evans發(fā)表的書(shū)籍:《Domain-Driven Design – Tackling Complexity in the Heart of Software》中文譯名:領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)—軟件核心復(fù)雜性應(yīng)對(duì)之道,池建強(qiáng)在2011年發(fā)表的一篇文章《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)和實(shí)踐》中是這樣形容DDD的:

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)事實(shí)上是針對(duì)OOAD的一個(gè)擴(kuò)展和延伸,DDD基于面向?qū)ο蠓治雠c設(shè)計(jì)技術(shù),對(duì)技術(shù)架構(gòu)進(jìn)行了分層規(guī)劃,同時(shí)對(duì)每個(gè)類進(jìn)行了策略和類型的劃分。

  本文主要介紹為什么我們?cè)诤阃?a href=/yuedu/kaiyuan/ target=_blank class=infotextkey>開(kāi)源內(nèi)部推廣DDD,我們?nèi)绾瓮ㄟ^(guò)開(kāi)發(fā) DDDLib 和 Koala 等工具來(lái)完善這一過(guò)程,推廣過(guò)程中遇到了哪些問(wèn)題,以及我們?nèi)绾谓鉀Q這一問(wèn)題。

  為什么選擇DDD

  傳統(tǒng)的模式的最大優(yōu)點(diǎn)在于開(kāi)發(fā)人員非常熟悉,開(kāi)發(fā)成本低,但它也有一些問(wèn)題:

  采用DDD開(kāi)發(fā)模式之前,傳統(tǒng)的開(kāi)發(fā)模型是最流行的Model-Dao-Service-UI開(kāi)發(fā)模型,通常是基于事務(wù)腳本(Transaction Script)和表模塊(Table Module)模式的實(shí)現(xiàn),這種模式通常是先設(shè)計(jì)表,再建模,實(shí)現(xiàn)容易依賴特定的表的一些特性,如存儲(chǔ)過(guò)程。基于表的設(shè)計(jì)模式容易帶來(lái)以下幾個(gè)問(wèn)題:

  • 業(yè)務(wù)建模完全是表的復(fù)制,無(wú)法真實(shí)反映業(yè)務(wù)。
  • 核心業(yè)務(wù)分散在各個(gè)地方,非常危險(xiǎn),修改擴(kuò)展難,且難以閱讀。

  這種開(kāi)發(fā)模式適合一些需求小,后續(xù)維護(hù)擴(kuò)展需求小的中小型項(xiàng)目,但在大型企業(yè)級(jí)系統(tǒng)或產(chǎn)品,擴(kuò)展維護(hù)或需求變量非常多的情況下,缺點(diǎn)也非常明顯。

  相對(duì)而言,DDD則有以下四點(diǎn)好處:

  1、面向?qū)ο螅P驼鎸?shí)反映業(yè)務(wù)現(xiàn)實(shí):使用DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),模型通常是業(yè)務(wù)的真實(shí)反映,業(yè)務(wù)集中在領(lǐng)域而不是分散在各Service中,有利于對(duì)業(yè)務(wù)的理解。

  2、使用領(lǐng)域統(tǒng)一建模語(yǔ)言:有利于業(yè)務(wù)溝通與建模: DDD倡導(dǎo)先對(duì)業(yè)務(wù)建模,而非關(guān)注表或腳本的設(shè)計(jì);在建模過(guò)程中,由于領(lǐng)域本身是對(duì)真實(shí)業(yè)務(wù)的反映與建模,因此與業(yè)務(wù)專家更容易溝通,打破技術(shù)與業(yè)務(wù)的溝通隔閡。

  3、可重用性高:DDD中,領(lǐng)域?qū)訛楹诵模總€(gè)領(lǐng)域?qū)ο蠖际且粋€(gè)相對(duì)完整的內(nèi)聚的業(yè)務(wù)對(duì)象描述,所以可以形成直接的復(fù)用。基于領(lǐng)域建模的設(shè)計(jì),并不會(huì)依賴特定的數(shù)據(jù)庫(kù)及特性,模型是可以完全重用且沒(méi)有技術(shù)上的沖突。

  4、業(yè)務(wù)越復(fù)雜,DDD的優(yōu)勢(shì)越明顯:領(lǐng)域模型采用OO設(shè)計(jì),通過(guò)將職責(zé)分配到相應(yīng)的模型對(duì)象或Service,可以很好的組織業(yè)務(wù)邏輯,當(dāng)業(yè)務(wù)變得復(fù)雜時(shí),領(lǐng)域模型顯出巨大的優(yōu)勢(shì)。

  DDDLib登場(chǎng)

  DDD本質(zhì)上是一種思想,并不是新技術(shù)。在恒拓開(kāi)源,由我們的楊宇老師和陳操總共同創(chuàng)作的DDDLib庫(kù),是對(duì)DDD思想的核心支持與實(shí)現(xiàn)。

  DDDLib是一整套支持DDD思想實(shí)現(xiàn)的類庫(kù),DDDLib下還是使用的 Hibernate、JPA或MyBatis、noSQL等技術(shù)為實(shí)現(xiàn)。

  如同DDD所要求樣,使用DDDLib 的項(xiàng)目分層圖為:

  • 用戶界面/展現(xiàn)層
    • 用于向用戶展現(xiàn)信息,處理用戶在界面上的請(qǐng)求,比如struts,tapestry,springMVC等頁(yè)面框架。
  • 應(yīng)用
    • 用來(lái)處理應(yīng)用的活動(dòng),不包含領(lǐng)域中的業(yè)務(wù)邏輯。
    • 應(yīng)用層可以用來(lái)處理一些與領(lǐng)域概念無(wú)關(guān)的攔截性質(zhì)的工作,比如日志,事務(wù)等。此外,應(yīng)用層也可以用來(lái)處理一些既不屬于展現(xiàn)層,也不屬于領(lǐng)域?qū)樱菍儆谀壳?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用相關(guān)的一些服務(wù)。比如資金轉(zhuǎn)賬的業(yè)務(wù)的讀取輸入功能(讀取輸入不是轉(zhuǎn)賬的核心業(yè)務(wù)含義)。
  • 領(lǐng)域?qū)?/li>
    • 此層是DDD的核心:領(lǐng)域?qū)ο螅I(lǐng)域服務(wù),倉(cāng)儲(chǔ)接口均位于此層。
    • 領(lǐng)域的信息,是業(yè)務(wù)軟件的核心所在。
    • 需要保留業(yè)務(wù)對(duì)象的狀態(tài),對(duì)業(yè)務(wù)對(duì)象及其狀態(tài)持久化的操作交給基礎(chǔ)設(shè)施層。
    • 領(lǐng)域?qū)討?yīng)該遵從以下原則:除非業(yè)務(wù)發(fā)生變化,否則其他任何變化均不應(yīng)該影響到領(lǐng)域?qū)印_@些其他變化包括:不同的展現(xiàn)框架,不同的頁(yè)面展現(xiàn)內(nèi)容,是否要分頁(yè),是否支持手機(jī)客戶端,是否公開(kāi)WebService,是否提供OpenAPI等等。
  • 基礎(chǔ)設(shè)施層
    • 此層作為其他層次的支撐,可以為領(lǐng)域?qū)拥某志没峁┲С郑?dāng)領(lǐng)域?qū)踊?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用層有特殊的業(yè)務(wù)或應(yīng)用需求(發(fā)送短信等)時(shí),它們會(huì)定義需求接口,然后在基礎(chǔ)設(shè)施層中實(shí)現(xiàn)這個(gè)接口,滿足特定的業(yè)務(wù)或應(yīng)用需求。

  DDDLib的核心實(shí)現(xiàn)如下:

  上圖就是使用 DDDLib 項(xiàng)目的整體技術(shù)架構(gòu)圖,也表明了DDDLib的整體原則:

  1. 領(lǐng)域?qū)邮菢I(yè)務(wù)核心,這一層不依賴任何特定的技術(shù)框架,保證它的業(yè)務(wù)純潔性。DDDLib中的領(lǐng)域?qū)又灰蕾嘕DK、DDDLib的Domain庫(kù)以及倉(cāng)儲(chǔ)接口及其它自定義接口。
  2. 使用倉(cāng)儲(chǔ)和查詢通道作為與存儲(chǔ)介質(zhì)相關(guān)的操作接口,隔離對(duì)特定數(shù)據(jù)庫(kù)技術(shù)或存儲(chǔ)介質(zhì)的依賴。
  3. 提供多種不同的IoC容器實(shí)現(xiàn)及InstanceFactory實(shí)例工廠,隔離對(duì)特定IOC 技術(shù)的依賴。
  4. 領(lǐng)域?qū)影ㄖ祵?duì)象、領(lǐng)域?qū)ο笠约邦I(lǐng)域服務(wù)三個(gè)要素,領(lǐng)域?qū)硬皇菙?shù)據(jù)庫(kù)操作層而是業(yè)務(wù)建模層。許多開(kāi)發(fā)者在使用的過(guò)程中,最終還是把領(lǐng)域?qū)幼鳛閿?shù)據(jù)庫(kù)操作層來(lái)使用,對(duì)實(shí)體的方法也是以數(shù)據(jù)庫(kù)的操作行為為標(biāo)準(zhǔn) ,如查詢,新增,刪除一個(gè)實(shí)體,最終依然回歸到以數(shù)據(jù)庫(kù)為中心的方向去了,這是需要避免的。
  5. 改變以數(shù)據(jù)庫(kù)為中心的核心是意識(shí)到業(yè)務(wù)行為才是核心,數(shù)據(jù)庫(kù)存儲(chǔ)是支撐。意識(shí)到數(shù)據(jù)庫(kù)是支撐非常關(guān)鍵,業(yè)務(wù)上的任何行為,在系統(tǒng)中最終需要存儲(chǔ)記錄,數(shù)據(jù)庫(kù)存儲(chǔ)是對(duì)業(yè)務(wù)實(shí)現(xiàn)的支撐,也可以使用文件,緩存或云空間等其它存儲(chǔ)介質(zhì)。想像一下,使用數(shù)據(jù)庫(kù)進(jìn)行設(shè)計(jì)的項(xiàng)目,最終就限定了存儲(chǔ)介質(zhì)為特定的數(shù)據(jù)庫(kù),如果下一次需要更換為云空間或緩存等其它存儲(chǔ)形式,就會(huì)發(fā)現(xiàn)整個(gè)系統(tǒng)需要重新設(shè)計(jì)開(kāi)發(fā),但使用DDDLib,只需更換倉(cāng)儲(chǔ)實(shí)現(xiàn),提供一個(gè)云空間的實(shí)現(xiàn)就行了,核心業(yè)務(wù)邏輯完全不需要變動(dòng)與修改。

  DDDLib在實(shí)現(xiàn)過(guò)程中也經(jīng)歷了內(nèi)部的不少爭(zhēng)議,經(jīng)過(guò)很多次的討論和打磨形成了現(xiàn)在的格局。在下面的部分,我將介紹DDDLib在幾個(gè)重要組件上的實(shí)現(xiàn)細(xì)節(jié)。

  DDDLib倉(cāng)儲(chǔ)的實(shí)現(xiàn)

  從DDDLib 1.0到3.5版本,倉(cāng)儲(chǔ)實(shí)現(xiàn)歷經(jīng)幾個(gè)階段,分別是:

  1. 給每個(gè)領(lǐng)域?qū)ο蠖x一個(gè)倉(cāng)儲(chǔ)接口及一個(gè)倉(cāng)儲(chǔ)實(shí)現(xiàn)。

    這種倉(cāng)儲(chǔ)實(shí)現(xiàn)非常受爭(zhēng)議,開(kāi)發(fā)人員并不認(rèn)可這種方式,倉(cāng)儲(chǔ)接口及實(shí)現(xiàn)非常多,一方面導(dǎo)致項(xiàng)目類太多,并且也帶來(lái)編碼的重復(fù)操作。

  2. 與spring data整合,給每個(gè)領(lǐng)域?qū)ο蠖x倉(cāng)儲(chǔ)接口,無(wú)須定義實(shí)現(xiàn)。這種模式對(duì)前面的模式有了優(yōu)化,只定義接口不定義實(shí)現(xiàn),但是spring data這種依賴方法名,參數(shù)來(lái)進(jìn)行查詢的模式,針對(duì)一些復(fù)雜的查詢,難以勝任。
  3. 提供默認(rèn)的hibernate及JPA的通用倉(cāng)儲(chǔ)接口。

    為每個(gè)倉(cāng)儲(chǔ)定義一個(gè)接口,這種模式慢慢的不被接受,使用spring data帶來(lái)的優(yōu)化方案,也有非常多的問(wèn)題,后面根據(jù)JPA的實(shí)體管理思路,于是形成了通用倉(cāng)儲(chǔ)接口及不同技術(shù)實(shí)現(xiàn)的思路,定義一個(gè)通用的倉(cāng)儲(chǔ)接口,包括通用的增刪改查數(shù)據(jù)庫(kù)行為。

  4. 支持MyBatis的通用倉(cāng)儲(chǔ)接口

    DDDLib的JPA及hibernate倉(cāng)儲(chǔ)實(shí)現(xiàn),這個(gè)方案是一個(gè)較佳的方案,所有領(lǐng)域?qū)嶓w使用通用的倉(cāng)儲(chǔ),避免了大量重復(fù)代碼,但DDDLib一直是基于Hibernate/JPA提供的實(shí)現(xiàn)與技術(shù)支持,在項(xiàng)目的使用過(guò)程中,經(jīng)常會(huì)遇到不適合使用Hibernate/JPA模式的項(xiàng)目,對(duì)MyBatis的需求也非常大,這種情況下,Koala團(tuán)隊(duì)定義實(shí)現(xiàn)了MyBatis的倉(cāng)儲(chǔ)實(shí)現(xiàn),并保證其與JPA/Hibernate模式下API的一致性。

  DDDLib中的DTO

  DTO,數(shù)據(jù)傳輸對(duì)象,領(lǐng)域?qū)ο箅m然有數(shù)據(jù)(屬性),但是領(lǐng)域?qū)ο笊厦孢€帶有操作,在某些場(chǎng)合不適合進(jìn)行傳輸,有些時(shí)候傳輸還需要序列化。但并不是所有的領(lǐng)域?qū)ο髮傩远伎梢员┞叮矣行傩钥赡芤喜ⅲ赡芤纸猓蟛庞欣谇岸说氖褂谩S谑蔷陀辛藢iT用來(lái)傳輸數(shù)據(jù)的DTO,只有屬性,沒(méi)有操作,必要的時(shí)候加上序列化標(biāo)記,實(shí)現(xiàn)遠(yuǎn)程調(diào)用。

  這是DDD中DTO的作用,但是DTO同時(shí)也帶來(lái)了實(shí)體與DTO的轉(zhuǎn)換性能問(wèn)題,在大數(shù)據(jù)量下尤其明顯。

  DDDLib中的數(shù)據(jù)庫(kù)支撐行為類

  在DDDLib實(shí)現(xiàn)中,提供了Repository以及QueryChannelService兩個(gè)接口,分別使用在領(lǐng)域?qū)右约?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用層,都是對(duì)數(shù)據(jù)庫(kù)的操作接口。

  SQL/HQL/JPQL寫在哪

  在使用DDDLib的過(guò)程中,不同的持久層框架的SQL語(yǔ)言不一樣,比如MyBatis使用的是SQL,Hibernate使用的是 HQL,JPA下使用的是JPQL。

  這些語(yǔ)句寫在哪兒在公司也經(jīng)歷過(guò)一番爭(zhēng)議與變更,歷史如下:

  1、寫在代碼中

public static Resource newResource(String name,String identifier,String level,String menuIcon){  Resource resource = null;  List<Resource> resources = Resource.getRepository().find("select r from Resource r where r.name = ? " + "and r.identifier = ?", new Object[]{name,identifier}, Resource.class);  ...} 

it知識(shí)庫(kù)DDD &amp;amp; DDDLib在恒拓開(kāi)源的發(fā)展歷程與推廣經(jīng)驗(yàn),轉(zhuǎn)載需保留來(lái)源!

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

主站蜘蛛池模板: 在线亚洲免费 | 在线看片成人免费视频 | 亚洲国产高清在线 | 免费观看亚洲视频 | 久久精品动漫网一区二区 | 久久国产精品无码视欧美 | 被滋润的艳妇疯狂呻吟白洁老七 | 久久精品亚洲热综合一本奇米 | 永久免费在线观看视频 | 友田真希息与子中文字幕 | 亲爱的妈妈6韩国电影免费观看 | 亚洲第一色网站 | 影音先锋影院中文无码 | 成人免费公开视频 | 国产精品97久久AV色婷婷 | 亚洲精品乱码久久久久久中文字幕 | 欧美男同gay粗大又长 | 一二三四在线视频社区 | 青柠在线观看视频在线高清 | 黄色三级视频在线观看 | 在线中文高清资源免费观看 | AV午夜午夜快憣免费观看 | 成人小视频免费在线观看 | 强壮的公次次弄得我高潮韩国电影 | 日操夜操天天操 | 亚洲国产成人精品无码区APP | 中文字幕无码亚洲视频 | 亚洲欧美成人综合 | 亚洲免费视频在线 | 久久精品亚洲热综合一本奇米 | 国产欧美一区二区三区在线看 | 精品国产国偷自产在线观看 | 国语对白刺激真实精品 | 国产色精品VR一区二区 | 精品视频在线观看视频免费视频 | 高h喷水荡肉爽文总攻 | 美国色情三级欧美三级纸匠情挑 | 一级毛片免费下载 | 精品国产福利一区二区在线 | 忘忧草在线影院www日本 | 日本xxx护士与黑人 日本xxxx裸体xxxx |