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的数据访问角度来构建。对象