前情提要:一共包含 如下六篇文章(篇幅精简,快速入门)
1、初识DDD
2、聚合、实体、值对象
3、仓储,封装持久化数据
4、端口和适配器
5、领域事件
6、领域服务,实现约定
DDD设计方法-4-端口和适配器
- 1、概念 什么是端口、适配器?
- 2、作用是什么?为什么要用?
- 3、端口和适配器的特性。(特征)
- 3.1 提到特性就不得不说的结构
- 4、端口适配器的实现概览(图)
- 5、端口适配器的实现步骤
- 5.1 整体绘图
- 5.2 具体代码 (1) 输入适配器(Controller)
- 5.2 具体代码 (2) 输入端口接口(InPortService)
- 5.2 具体代码 (3) 应用服务实现:InPortServiceImpl
- 5.2 具体代码 (4) 输出端适配器(OuPortRepository)及实现
- 5.2 具体代码 (5、6) 扩展实现->
1、概念 什么是端口、适配器?
端口(Ports):定义系统与外部系统之间的接口。它们是抽象的接口,用于描述系统需要什么功能和服务。
适配器(Adapters):实现端口的具体类,负责将外部系统或组件接入到我们的系统中。适配器可以是输入适配器,也可以是输出适配器。
2、作用是什么?为什么要用?
标准定义:端口和适配器定义了服务的标准行为和外部依赖,提高了代码的可读性和可维护性。( 白话文: 类似于封装标准及对外服务外层包装 )
隔离变化:当外部系统变化时,只需更换或修改适配器,无需改动核心业务逻辑。
促进测试:可以使用模拟适配器来测试核心逻辑,而不依赖真实的外部系统。
3、端口和适配器的特性。(特征)
抽象性:端口提供了服务行为的抽象描述,明确了服务的功能和外部依赖。
独立性:端口独立于具体实现,允许服务实现的灵活替换或扩展。
灵活性:可以为同一端口提供不同的适配器实现,以适应不同的运行环境或需求。
3.1 提到特性就不得不说的结构
输入端口(Inbound Ports):定义应用服务的接口,处理外部请求。
输出端口(Outbound Ports):定义系统所需的外部服务接口。
输入适配器(Inbound Adapters):控制器(Controllers),REST API,消息监听器等,负责接受外部请求并调用输入端口。
输出适配器(Outbound Adapters):例如,数据库访问层,外部服务客户端等,实现输出端口的接口。
4、端口适配器的实现概览(图)
5、端口适配器的实现步骤
5.1 整体绘图
5.2 具体代码 (1) 输入适配器(Controller)
@RestController
@RequestMapping("/orders")
public class OrderController {@Resourceprivate InPortForOrderService orderService;@PostMapping("/save")public ResponseEntity<Void> createOrder(@RequestBody Order orderDTO) {orderService.createOrder(orderDTO);return new ResponseEntity<>(HttpStatus.CREATED);}
}
5.2 具体代码 (2) 输入端口接口(InPortService)
public interface InPortForOrderService {void createOrder(Order orderDTO);
}
5.2 具体代码 (3) 应用服务实现:InPortServiceImpl
@Service
public class InPortForOrderServiceImpl implements InPortForOrderService {@Resourceprivate OutPortOrderRepository outPortOrderRepository;@Overridepublic void createOrder(Order orderDTO) {outPortOrderRepository.saveOrder(orderDTO);}}
5.2 具体代码 (4) 输出端适配器(OuPortRepository)及实现
public interface OutPortOrderRepository {void saveOrder(Order order);void findById(Order order);
}
@Service
public class OutPortOrderRepositoryImpl implements OutPortOrderRepository {@AutowiredMap<String, CreateOutPortOrderRepository> fileStoreServiceMap;@Overridepublic void saveOrder(Order order) {fileStoreServiceMap.get(order.getType()).createOrder(order);}@Overridepublic void findById(Order order) {//此处可以继续扩展}}
5.2 具体代码 (5、6) 扩展实现->
public interface CreateOutPortOrderRepository {void createOrder(Order order);}
@Service
@Component(value = "saDbCreateOutPortOrderRepository")
public class SaDbCreateOutPortOrderRepositoryImpl implements CreateOutPortOrderRepository {// 本地仓库不够创建采购订单 从第三方服务商购买public void createOrder(Order order) {//处理逻辑。。。。。。 当前操作人...操作时间//调用本地仓储接口,之后由基础设施层做具体实现 --> 生成工单//调用本地仓储接口,之后由基础设施层做具体实现 --> 生成工单流水System.out.println("采购工单创建 - 从第三方服务商购买 " );}
}
@Service
@Component(value = "thrCreateOutPortOrderRepositoryImpl")
public class ThrCreateOutPortOrderRepositoryImpl implements CreateOutPortOrderRepository {// 调用订单服务中心才可以创建调拨工单 (需要其他省市公司帮忙 从人家仓库拿东西到下订单的仓库)public void createOrder(Order order) {//第三方鉴权参数//实际工单参数//调用本地仓储接口,之后由基础设施层做具体实现 --> 外部接口调用记录System.out.println("调用订单服务中心创建工单 需要其他省市公司帮忙 从人家仓库拿东西到下订单的仓库 " );}
}