一、解耦领域层和基础层       

   DDD严格的分层架构告诉我们,每一层只能与其下方的一层发生耦合。因此用户接口层只与应用层发生交互,应用层往下只与领域层发生交互,领域层往下只与基础层发生交互。

    在传统的代码分层结构Controller—Service—Dao结构中,经常能看到在Service业务实现层的代码中嵌入SQL,或者在其中频繁出现修改数据对象并调用DAO的情况。这样,基础层的数据处理逻辑就渗透到了业务逻辑代码中。

    在DDD的分层结构中,如果出现上述情况,则基础层的数据处理逻辑就渗透到了领域层,领域层中的领域模型就难以聚焦在业务逻辑上,对外层的基础层产生了依赖。而一旦涉及到数据逻辑的修改,就要到领域层中去修改代码,重新调试领域层与基础层的交互,或者当切换异构数据库类型时,需要大量修改领域层的代码,将业务逻辑和数据处理逻辑重新适配(主要在于异构数据库导致的SQL或数据对象调整),因此技术升级会变得特别麻烦。

    本文要讲的仓储模式就是用来解耦领域层和基础层的,降低他们之间的耦合和相互影响

    

  二、仓储模式

       为了解耦领域逻辑和数据处理逻辑,在中间加了薄薄的一层仓储。

    仓储模式包含仓储接口和仓储实现,仓储接口面向领域层提供基础层数据处理相关的接口,仓储实现则完成仓储接口对应的数据持久化相关的逻辑处理。一个聚合配备一个仓储,由仓储完成聚合数据的持久化。领域层逻辑面向仓储接口编程,聚合内的数据持久化过程为DO(领域对象)转PO(持久化对象)。

    当需要更换数据库类型,或者更改数据处理逻辑时,我们就可以保持业务逻辑接口不动,只修改仓储实现,保证了领域层业务逻辑的干净和纯洁。

    如下示例为一个人员聚合中对人员实体的仓储模式实现:

    人员DO和人员PO定义:  

/*** 人员聚合* @author test11*/
public class Person {//人员idprivate String id;//姓名private String name;//地址(值对象)private Address address;//上班行为private void goWork(){}//下班行为private void leaveWork(){}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}}
/*** 人员聚合的持久化PO* @author test11*/
public class PersonPO {//人员idprivate String id;//姓名private String name;//地址private Address address;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}
}
/*** 地址值对象*/
public class Address {//省份private String province;//城市private String city;//街道private String street;
}

    仓储接口定义:

/*** 人员聚合仓储接口* @author test11*/
public interface PersonRepository {/*** 添加人员*/void addPerson(PersonPO personPO);/*** 更新人员*/void updatePerson(PersonPO personPO);/*** 根据id查找人员PO对象* @return*/PersonPO findById(String id);
}

    

    仓储接口实现:

/*** 人员仓储实现* @author test11*/
public class PersonRepositoryImpl implements PersonRepository{@ResourcePersonDao personDao;@Overridepublic void addPerson(PersonPO personPO) {personDao.addPerson(personPO);}@Overridepublic void updatePerson(PersonPO personPO) {personDao.updatePerson(personPO);}@Overridepublic PersonPO findById(String id) {return personDao.findById(id);}
}

    

    人员领域服务实现:后面基础层发生了变化,则领域层无需动任何代码,只要仓储接口不变,领域层的逻辑就可以一直保持不变,维护了领域层的稳定性。领域服务是可以做成企业级可复用的服务的,因此稳定性必须有保障。

import javax.annotation.Resource;/*** 人员领域服务聚合类* @author test11*/
public class PersonDomainService {@ResourcePersonRepository personRepository;public void addPerson(PersonPO personPO) {personRepository.addPerson(personPO);}
}

 

  三、工厂模式

  DO对象创建时,需要确保聚合根和它依赖的对象同时被创建,如果这项工作交给聚合根来实现,则聚合根的构造函数将变得异常庞大,所以我们把通用的初始化DO的逻辑,放到工厂中去实现,通过工厂模式封装聚合内复杂对象的创建过程,完成聚合根,实体和值对象的创建。DO对象创建时,通过仓储从数据库中获取PO对象,通过工厂完成PO到DO的转换

  工厂中还可以包含DO到PO对象的转换过程,方便完成数据的持久化。

/*** Person聚合的工厂* DO和PO的转换* @author test11*/
public class PersonFactory {/*** 人员PO到领域对象的数据初始化* @param personPO* @return*/protected Person createPerson(PersonPO personPO){Person person = new Person();person.setId(personPO.getId());person.setName(personPO.getName());person.setAddress(personPO.getAddress());return person;}/*** 领域对象到持久化对象PO的转换* @param person* @return*/protected PersonPO createPersonPO(Person person){PersonPO personPO = new PersonPO();personPO.setId(person.getId());personPO.setName(person.getName());personPO.setAddress(person.getAddress());return personPO;}}

  

DDD—Repository仓储工厂模式相关推荐

  1. 这 3 种 DDD 分层架构的模式,你掌握了么?

    -     前言    - 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和分层架构的相关知识. -     DDD 的基本概念     - DDD(Domain DrivenDesign, ...

  2. Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。

    写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗? ...

  3. Java中的简单工厂模式(转)

    Java中的简单工厂模式 举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人 话说:"天地开辟,未有人民,女娲抟土为人."女娲需要用土造出一个个的人,但在女娲造出人之前, ...

  4. AbstractFactory抽象工厂模式(创建型模式)

    1.new 的问题 常见的对象创建方法: //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对具体实例的变化 怎么理解上面这句话呢? 可以这样理解:我 ...

  5. 第六周 Java语法总结_设计原则_工厂模式_单例模式_代理模式(静态代理_动态代理)_递归_IO流_网络编程(UDP_TCP)_反射_数据库

    文章目录 20.设计原则 1.工厂模式 2.单例模式 1)饿汉式 2)懒汉式 3.Runtime类 4.代理模式 1)静态代理 2)动态代理 动态代理模板 21.递归 22.IO流 1.File 2. ...

  6. 个人理解简单工厂模式和策略模式的区别

    刚刚接触设计模式的时候,我相信单例模式和工厂模式应该是用的最多的,毕竟很多的底层代码几乎都用了这些模式.自从接触了一次阿里的公众号发的一次文章关于 DDD的使用 以后,就逐渐接触了策略模式.现在在项目 ...

  7. 设计模式(java)--简单工厂模式之女娲造人.水果农场

    女娲抟土造人 话说:"天地开辟,未有人民,女娲抟土为人."女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面. 女娲造人,这就是简单工厂模式的应用.  ...

  8. java基础5:工厂模式、单例模式、File文件类、递归、IO流、Properties配置文件、网络编程、利用IO流模拟注册登录功能、关于反射、JDK动态代理

    1.工厂模式 23种java设计模式之一 1)提供抽象类(基类) 2)提供一些子类,完成方法重写 3)提供一个接口:完成具体子类的实例化对象的创建,不能直接new子类,构造函数私有化. 优点:具体的子 ...

  9. 【Spring】工厂模式解耦

    问题: 程序的耦合    耦合:程序间的依赖关系    包括:类之间的依赖       方法之间的依赖 解耦:降低程序之间的耦合关系    实际开发:编译期不依赖,运行期才依赖    解耦思路:    ...

最新文章

  1. 【畅谈百度轻应用】云时代·轻应用·大舞台
  2. 正则表达式学习实例1
  3. 把一些11年老博客上的文章转移过来了
  4. java hellowordk_Rhythmk 一步一步学 JAVA(4):Spring3 MVC 之 Hello Word
  5. Spring+Velocity中模板路径的问题
  6. Pytorch损失函数losses简介
  7. 图像处理和计算机视觉中的经典论文(转)
  8. Android 网络代理的创建
  9. Java swing实现一组图片自动轮播
  10. winform利用html开发,Winform开发框架之HTML编辑控件介绍
  11. keil报错:*** FATAL ERROR L250,注册2032年
  12. 为什么硅谷初级程序员工资堪比腾讯T3技术专家级
  13. Google TPU的发展历程与思考(一)
  14. 低级程序员和高级程序员的区别
  15. linux c蜂鸣器驱动程序,嵌入式Linux设备驱动程序设计——蜂鸣器驱动程序
  16. dump java崩溃自动 不生成_Java如何生成Heap Dump及OOM问题排查
  17. win7 host 中 vbox 虚拟机无法 attach USB device的问题
  18. js 防止网络慢时 表单重复提交问题
  19. Git 和 GitHub 快速入门
  20. OSChina 周日乱弹——如何请假不被老板骂

热门文章

  1. 日文输入法键盘分部图
  2. 图片转.eps格式的方法
  3. 电商数据监测的几个角度
  4. Linux常用命令(快收藏起来)
  5. hge source explor 0x6 input module
  6. R语言用read.table()函数读取txt文件时报错incomplete final line found by readTableHeader
  7. 利用 Addax 异构迁移数据到 Databend
  8. 1000BASE-T/SX/LX/EX/ZX代表哪种SFP光模块?
  9. jar包 使用 -xvf 和 cvfm 解压和打包问题
  10. JDK17.0.2下载与安装教程,超级详细