DDD領域驅動模型設計

背景

使用DDD開發大概也有五個月的時間了,由於當時公司導師的推薦,第一次接觸DDD領域驅動到現在徹底迷戀這種開發的模式,爲其思想的奧妙所折服,一直以來,總想花一點時間來總結一下,正直光棍節(天貓狂歡購物節)當天,“靜下心來”(PS:沒有人民幣)總結一下。

說起DDD不得不說一篇文章:http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html

第一次接觸,就是這篇文章,當時看起來晦澀難懂,後來慢慢的讀起來,每一次都有精神的提升,網上也有很多關於DDD的介紹,這裏將不會在介紹概念什麼的,下邊主要是自己工作過程中的一些總結。

如何快速入門

第一次接觸DDD的時候,概念高深莫測,奧祕深不可見,大有不知所云的趨勢,後來導師的引導,讓直接從項目中直接入手,遂逐步揭開其一層層霧紗,如圖1:

這裏寫圖片描述

DDD一般的分層結構和調用順序如上所述,infrastructure是基礎設施層,domain是領域層,application是應用層,facade和facade-impl是門面層(前者是門面接口層,後者是門面實現層),webapp是用戶接口層(採用web形式)。

下邊是一種項目的分層圖,採用的Maven管理代碼。圖2:

這裏寫圖片描述

分層的介紹

1、web:首先包含網站前端,如果使用SpringMVC的話,還需要其Controler,

這裏寫圖片描述

該Controler層主要是用於接收HTTP請求和返回客戶端,一般不進行邏輯上的判斷,其代表了用戶可以進行的操作,一般不涉及領域驅動的思想,示例代碼:

@ResponseBody
    @RequestMapping(value = "/create", method = RequestMethod.POST)    public String create(AirlineWhiteListDTO airlineWhiteListDTO) {
        MDC.put(ConstString.TRACE_ID, LogUtil.getTraceId(ConstAirlineWhiteList.CREATE));
        Response response = airlineWhiteListFacade.create(airlineWhiteListDTO);        return super.handleResponse(response);
    }12345671234567

第一行使用MDC用於記錄(打log)http請求的順序和調用的方法,第二行調用“門面層”facede,獲得Response返回對象,第三行用於判斷是返回界面還是返回data等操作,即時SpringMVC的ModalAndView;

2、facade和facade-impl一個是門面層接口一個是門面層接口的實現類,示例代碼:

@Autowired
IAirlineWhiteListApplication airlineWhiteListApplication;public Response create(AirlineWhiteListDTO airlineWhiteListDTO) {        Response response = new Response();
        try {
            AirlineWhiteList airlineWhiteList = AirlineWhiteListAssembler.toEntity(airlineWhiteListDTO);
            airlineWhiteListApplication.create(airlineWhiteList);
        } catch (Exception e) {            response = new Response(e);
        }
        return response;
    }1234567891011121312345678910111213

可以看出這是在web的controller中訪問的方法,主要進行數據的組裝(實體對象和數據傳輸對象的轉換),以及返回對象Response的轉換。

之所以成爲門面層,我們暫可認爲是我們用戶可以看到的整個系統的東西,例如上述中的Response就是返回給用戶看的東西。

3、Application層,上述的facade調用到了application中的方法,

@Injectprivate AirlineWhiteList airlineWhiteList;public boolean create(AirlineWhiteList airlineWhiteList) {        return this.airlineWhiteList.add(airlineWhiteList);
    }123456123456

這一層主要是操作實體對象的,是於數據更近一層的操作,主要定義了用戶所擁有的方法和屬性,操作實體對象層,將實體對象所有的方法展示出來供用戶使用;

4、domain層,數據實體層,相比MVC中的modal簡單的只是數據庫的映射,這種“毫無靈魂”的對象,領域模型中不但有一個實體對象的屬性還有其方法,(我們可以在實際使用的時候使用繼承DTO的方式),在這一層中定義了實體對象操作數據庫的方法;

這裏我們的實體對象不僅是擁有屬性還具有方法的,就像一個人一樣,我們不但擁有做人的基本特徵(兩手、兩腳等),我們還有屬於自己的技能(方法),這樣的話纔是一個擁有靈魂的東西;

5、infra這一層包含了訪問數據庫的方法、數據倉儲(sql、nosql、api)和一些工具類,service等;

由於是domain層調用該層的,實體對象的操作固然包含CRUD,既是我們需要進行對數據庫的操作,當我們只有一個數據源的時候,很簡單,但是後期項目中數據源可能會增加,可能會添加緩存等,這樣的話使用原來的MVC模式的話,我們可能需要修改很多,如下圖:

這裏寫圖片描述

但是使用DDD的話,由於我們的Domain調用的是infra 數據倉庫Repository接口,Repository中定義了訪問數據源的方法,這樣的話,當我門新增數據源的時候,我們的Domain層以上都無需修改,只需進行infra層的修改即可。
這裏寫圖片描述

上圖中有2個數據源,一個是sql一個是nosql,在方框中的Repository即調用的是nosql和sql中的方法,這樣的話Domain直接調用Repository即可。

領域驅動的示例:

如果想快速的領回DDD的奧妙,這裏有一個案例,一個很不錯的開源系統,使用的正是DDD思想,可以把代碼下載下來仔細研究,其中的思想是很不錯、很不錯的,地址如下:http://www.openkoala.org/

總結:

類比MVC“啞鈴式”的分層結構中,Model和View代碼少,Controller代碼臃腫的佈局格式,DDD擁有更多的分層,各層之間各司其職,協調工作,一步步調用,井然有序,對於後期的維護,只要是熟悉DDD的開發人員都可以很好的維護。

http://blog.csdn.net/xlgen157387/article/details/49782697

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章