DDD—Repository仓储工厂模式
一、解耦领域层和基础层
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仓储工厂模式相关推荐
- 这 3 种 DDD 分层架构的模式,你掌握了么?
- 前言 - 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和分层架构的相关知识. - DDD 的基本概念 - DDD(Domain DrivenDesign, ...
- Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。
写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗? ...
- Java中的简单工厂模式(转)
Java中的简单工厂模式 举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人 话说:"天地开辟,未有人民,女娲抟土为人."女娲需要用土造出一个个的人,但在女娲造出人之前, ...
- AbstractFactory抽象工厂模式(创建型模式)
1.new 的问题 常见的对象创建方法: //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对具体实例的变化 怎么理解上面这句话呢? 可以这样理解:我 ...
- 第六周 Java语法总结_设计原则_工厂模式_单例模式_代理模式(静态代理_动态代理)_递归_IO流_网络编程(UDP_TCP)_反射_数据库
文章目录 20.设计原则 1.工厂模式 2.单例模式 1)饿汉式 2)懒汉式 3.Runtime类 4.代理模式 1)静态代理 2)动态代理 动态代理模板 21.递归 22.IO流 1.File 2. ...
- 个人理解简单工厂模式和策略模式的区别
刚刚接触设计模式的时候,我相信单例模式和工厂模式应该是用的最多的,毕竟很多的底层代码几乎都用了这些模式.自从接触了一次阿里的公众号发的一次文章关于 DDD的使用 以后,就逐渐接触了策略模式.现在在项目 ...
- 设计模式(java)--简单工厂模式之女娲造人.水果农场
女娲抟土造人 话说:"天地开辟,未有人民,女娲抟土为人."女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面. 女娲造人,这就是简单工厂模式的应用. ...
- java基础5:工厂模式、单例模式、File文件类、递归、IO流、Properties配置文件、网络编程、利用IO流模拟注册登录功能、关于反射、JDK动态代理
1.工厂模式 23种java设计模式之一 1)提供抽象类(基类) 2)提供一些子类,完成方法重写 3)提供一个接口:完成具体子类的实例化对象的创建,不能直接new子类,构造函数私有化. 优点:具体的子 ...
- 【Spring】工厂模式解耦
问题: 程序的耦合 耦合:程序间的依赖关系 包括:类之间的依赖 方法之间的依赖 解耦:降低程序之间的耦合关系 实际开发:编译期不依赖,运行期才依赖 解耦思路: ...
最新文章
- 【畅谈百度轻应用】云时代·轻应用·大舞台
- 正则表达式学习实例1
- 把一些11年老博客上的文章转移过来了
- java hellowordk_Rhythmk 一步一步学 JAVA(4):Spring3 MVC 之 Hello Word
- Spring+Velocity中模板路径的问题
- Pytorch损失函数losses简介
- 图像处理和计算机视觉中的经典论文(转)
- Android 网络代理的创建
- Java swing实现一组图片自动轮播
- winform利用html开发,Winform开发框架之HTML编辑控件介绍
- keil报错:*** FATAL ERROR L250,注册2032年
- 为什么硅谷初级程序员工资堪比腾讯T3技术专家级
- Google TPU的发展历程与思考(一)
- 低级程序员和高级程序员的区别
- linux c蜂鸣器驱动程序,嵌入式Linux设备驱动程序设计——蜂鸣器驱动程序
- dump java崩溃自动 不生成_Java如何生成Heap Dump及OOM问题排查
- win7 host 中 vbox 虚拟机无法 attach USB device的问题
- js 防止网络慢时 表单重复提交问题
- Git 和 GitHub 快速入门
- OSChina 周日乱弹——如何请假不被老板骂
热门文章
- 日文输入法键盘分部图
- 图片转.eps格式的方法
- 电商数据监测的几个角度
- Linux常用命令(快收藏起来)
- hge source explor 0x6 input module
- R语言用read.table()函数读取txt文件时报错incomplete final line found by readTableHeader
- 利用 Addax 异构迁移数据到 Databend
- 1000BASE-T/SX/LX/EX/ZX代表哪种SFP光模块?
- jar包 使用 -xvf 和 cvfm 解压和打包问题
- JDK17.0.2下载与安装教程,超级详细