DDD中的Repository(倉儲):協調領域和數據映射層,利用相似與集合的接口來訪問領域對象。——《領域驅動設計-軟件核心複雜性應對之道》java
倉儲是DDD中產生的概念,也就是說,若是應用程序不是基於領域驅動設計的,那在設計中使用倉儲是否是會有不合適的地方呢?spring
Eric Evans 在《領域驅動設計-軟件核心複雜性應對之道》定義中明確的那樣:協調領域和數據映射層,兩個關鍵字領域和數據映射層,這裏面的領域是指領域模型(實體和值對象),這是橋的一頭,另外一頭就是數據映射層,也就是咱們常說的 ORM 工具。架構
除了這兩個關鍵詞,還有一個動詞就是協調,倉儲協調的是什麼?怎麼協調的?這個概念須要明確下,橋的一頭-領域模型(主要是實體對象),這個就很少說了,橋的另外一頭-ORM(對象關係映射),其實倉儲協調的是 ORM 中的「O」,也就是對象的概念,它是在數據映射層之上的,是一種概念,而不是一種實現。框架
倉儲表明一個聚合的集合,倉儲用來存儲和刪除聚合,但同時提供針對聚合的顯式查詢以及彙總。ide
下面咱們首先來看一個簡單倉儲的定義:工具
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的數據訪問角度來構建。對象