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

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

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

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

  本文主要介紹為什么我們在恒拓開源內(nèi)部推廣DDD,我們?nèi)绾瓮ㄟ^開發(fā) DDDLib 和 Koala 等工具來完善這一過程,推廣過程中遇到了哪些問題,以及我們?nèi)绾谓鉀Q這一問題。

  為什么選擇DDD

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

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

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

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

  相對而言,DDD則有以下四點好處:

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

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

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

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

  DDDLib登場

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

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

  如同DDD所要求樣,使用DDDLib 的項目分層圖為:

  • 用戶界面/展現(xiàn)層
    • 用于向用戶展現(xiàn)信息,處理用戶在界面上的請求,比如struts,tapestry,springMVC等頁面框架。
  • 應(yīng)用
    • 用來處理應(yīng)用的活動,不包含領(lǐng)域中的業(yè)務(wù)邏輯。
    • 應(yīng)用層可以用來處理一些與領(lǐng)域概念無關(guān)的攔截性質(zhì)的工作,比如日志,事務(wù)等。此外,應(yīng)用層也可以用來處理一些既不屬于展現(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ù),倉儲接口均位于此層。
    • 領(lǐng)域的信息,是業(yè)務(wù)軟件的核心所在。
    • 需要保留業(yè)務(wù)對象的狀態(tài),對業(yè)務(wù)對象及其狀態(tài)持久化的操作交給基礎(chǔ)設(shè)施層。
    • 領(lǐng)域?qū)討?yīng)該遵從以下原則:除非業(yè)務(wù)發(fā)生變化,否則其他任何變化均不應(yīng)該影響到領(lǐng)域?qū)印_@些其他變化包括:不同的展現(xiàn)框架,不同的頁面展現(xiàn)內(nè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ā)送短信等)時,它們會定義需求接口,然后在基礎(chǔ)設(shè)施層中實現(xiàn)這個接口,滿足特定的業(yè)務(wù)或應(yīng)用需求。

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

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

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

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

  DDDLib倉儲的實現(xiàn)

  從DDDLib 1.0到3.5版本,倉儲實現(xiàn)歷經(jīng)幾個階段,分別是:

  1. 給每個領(lǐng)域?qū)ο蠖x一個倉儲接口及一個倉儲實現(xiàn)。

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

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

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

  4. 支持MyBatis的通用倉儲接口

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

  DDDLib中的DTO

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

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

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

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

  SQL/HQL/JPQL寫在哪

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

  這些語句寫在哪兒在公司也經(jī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知識庫DDD &amp;amp; DDDLib在恒拓開源的發(fā)展歷程與推廣經(jīng)驗,轉(zhuǎn)載需保留來源!

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

主站蜘蛛池模板: 崇信县| 莱芜市| 乐平市| 工布江达县| 易门县| 甘谷县| 罗江县| 股票| 黄石市| 日喀则市| 平陆县| 河间市| 台安县| 颍上县| 福清市| 滁州市| 山阴县| 大港区| 财经| 同德县| 房产| 许昌县| 大兴区| 宁乡县| 宜丰县| 新龙县| 江山市| 岐山县| 诏安县| 红原县| 高平市| 吉水县| 平昌县| 丰台区| 吉林省| 江西省| 郧西县| 泗水县| 义乌市| 诸城市| 繁昌县|