DDD(十)--倉儲

一、引言

DDD中的Repository(倉儲):協調領域和數據映射層,利用相似與集合的接口來訪問領域對象。——《領域驅動設計-軟件核心複雜性應對之道》java

倉儲是DDD中產生的概念,也就是說,若是應用程序不是基於領域驅動設計的,那在設計中使用倉儲是否是會有不合適的地方呢?spring

Eric Evans 在《領域驅動設計-軟件核心複雜性應對之道》定義中明確的那樣:協調領域和數據映射層,兩個關鍵字領域和數據映射層,這裏面的領域是指領域模型(實體和值對象),這是橋的一頭,另外一頭就是數據映射層,也就是咱們常說的 ORM 工具。架構

除了這兩個關鍵詞,還有一個動詞就是協調,倉儲協調的是什麼?怎麼協調的?這個概念須要明確下,橋的一頭-領域模型(主要是實體對象),這個就很少說了,橋的另外一頭-ORM(對象關係映射),其實倉儲協調的是 ORM 中的「O」,也就是對象的概念,它是在數據映射層之上的,是一種概念,而不是一種實現。框架

二、DDD中的倉儲

倉儲表明一個聚合的集合,倉儲用來存儲和刪除聚合,但同時提供針對聚合的顯式查詢以及彙總。ide

2.一、倉儲與數據訪問層的區別

  • 倉儲限定了只能經過聚合根來持久化和檢索領域對象,以確保全部改動和不變性由聚合處理。
  • 倉儲經過隱藏聚合持久化和檢索的底層技術實現領域層的的持久化無關性(即領域層不須要知道如何持久化領域對象)。
  • 倉儲在數據模型和領域模型定義了一個邊界。

2.二、倉儲舉例

下面咱們首先來看一個簡單倉儲的定義:工具

public interface WeChatUserRepository {
	WeChatUser save(WeChatUser data);
	void delete(WeChatUser data);
}

通常狀況下,倉儲由應用服務層調用。倉儲定義應用服務執行業務用例時須要的全部的數據訪問方法。而倉儲的實現一般位於基礎架構層,由持久化框架來支撐。如下的倉儲實現是藉助於ORM框架spring data jpa,它扮演一個管理員的角色,負責領域模型和數據模型的映射。設計

@Service
public class WeChatUserServiceImpl implements WeChatUserService{

	@Autowired
	private WeChatUserRepository weChatUserRepository;
	
	@Override
	public WeChatUser save(WeChatUser data) {
		return weChatUserRepository.save(data);
	}

	@Override
	public void delete(WeChatUserVo data) {
		WeChatUser target = new WeChatUser();
		BeanUtils.copyProperties(data, target);
		weChatUserRepository.delete(target);
	}

}

從上面咱們能夠看出,將領域模型的持久化轉移到基礎設施層,隱藏了領域模型的技術複雜性,從而使領域對象可以專一於業務概念和邏輯,保持你的領域模型和技術持久化框架的獨立性,這樣領域模型能夠隔離來自底層持久化技術的影響。code

倉儲是原則上是領域模型與持久化存儲之間明確的契約,對於調用倉儲中方法的服務層來講也能夠稱之爲管理員,當你須要向管理員報告拿什麼東西的時候確定要明確你要拿什麼,因此倉儲定義的接口方法不單單是CURD方法,倉儲接口的定義應該根據應用程序的用例需求來建立,而不是從相似CURD的數據訪問角度來構建。對象

3. 小結

  • 倉儲做爲領域模型和數據模型的中介,它負責映射領域模型到持久化存儲。
  • 倉儲實現了透明持久化,即領域層不須要關注領域對象如何持久化。
  • 倉儲是一個契約,而不是數據訪問層。它明確代表聚合所必需的數據操做。
  • ORM框架不是倉儲。倉儲是一種架構模式。ORM用來以面向對象的方式來表示數據模型。倉儲使用ORM來協調領域模型和數據模型。
  • 倉儲適用於具備豐富領域模型的限界上下文。對於沒有複雜業務邏輯的簡單限界上下文,直接使用持久化框架便可。
  • 倉儲用於管理單個聚合,它不該該控制事務。
相關文章
相關標籤/搜索