当前位置: 首页 > news >正文

DDD-014:工厂(Factory)

DDD-014:工厂(Factory)

14.1 工厂的概念与职责

14.1.1 什么是工厂?

【原理】
工厂(Factory)是 DDD 中用于封装复杂对象创建逻辑的机制。当一个对象的创建过程过于复杂,不适合直接使用构造函数时,就需要使用工厂来封装创建过程。

工厂的核心职责:

  • 封装创建逻辑:隐藏复杂的对象组装过程
  • 保证有效性:确保创建出的对象始终处于有效状态
  • 表达意图:通过工厂方法名清晰表达创建的意图
  • 分离关注点:将创建逻辑与业务逻辑分离

14.1.2 工厂的职责边界

【代码示例】

// 工厂只负责创建,不负责业务逻辑// ✅ 工厂职责:创建对象publicclassOrderFactory{publicOrdercreateOrder(CustomerIdcustomerId,List<OrderItemInfo>items){// 创建和组装对象Orderorder=newOrder(OrderId.generate(),customerId);for(OrderItemInfoitem:items){order.addItem(item.getProductId(),item.getProductName(),item.getPrice(),item.getQuantity());}returnorder;}}// ❌ 工厂不应该包含业务逻辑publicclassOrderFactory{publicOrdercreateAndSubmitOrder(CustomerIdcustomerId,List<OrderItemInfo>items){Orderorder=newOrder(OrderId.generate(),customerId);order.submit();// 业务逻辑,不应该在工厂order.pay(payment);// 业务逻辑,不应该在工厂returnorder;}}

14.2 工厂的使用场景

14.2.1 需要使用工厂的场景

【历史架构问题】

// ❌ 传统做法:复杂构造逻辑散落各处@ServicepublicclassOrderService{publicOrdercreateOrder(CreateOrderRequestrequest){// 大量构造逻辑散落在Service中Orderorder=newOrder();order.setId(UUID.randomUUID().toString());order.setCustomerId(request.getCustomerId());order.setStatus("DRAFT");order.setCreatedAt(newDate());order.setItems(newArrayList<>());order.setTotalAmount(BigDecimal.ZERO);for(OrderItemRequestitemReq:request.getItems()){OrderItemitem=newOrderItem();item.setId(UUID.randomUUID().toString());item.setProductId(itemReq.getProductId());item.setProductName(itemReq.getProductName());item.setPrice(itemReq.getPrice());item.setQuantity(itemReq.getQuantity());order.getItems().add(item);order.setTotalAmount(order.getTotalAmount().add(itemReq.getPrice().multiply(newBigDecimal(itemReq.getQuantity()))));}// 问题:// 1. 构造逻辑复杂,散落在Service中// 2. 容易遗漏必要的初始化// 3. 代码重复,多处创建逻辑// 4. 无法保证对象有效性returnorder;}}

【DDD 如何解决】

// ✅ DDD工厂:封装创建逻辑publicclassOrder{// 私有构造函数,防止外部直接实例化privateOrder(OrderIdid,CustomerIdcustomerId){this.id=id;this.customerId=customerId;this.status=OrderStatus.DRAFT;this.items=newArrayList<>();this.totalAmount=Money.ZERO;this.createdAt=LocalDateTime.now();}// 静态工厂方法:表达创建意图publicstaticOrdercreate(CustomerIdcustomerId){Objects.requireNonNull(customerId,"客户ID不能为空");Orderorder=newOrder(OrderId.generate(),customerId);order.registerEvent(newOrderCreatedEvent(order.id,customerId));returnorder;}// 静态工厂方法:从购物车创建publicstaticOrdercreateFromCart(CustomerIdcustomerId,ShoppingCartcart){Objects.requireNonNull(customerId,"客户ID不能为空");Objects.requireNonNull(cart,"购物车不能为空");Orderorder=newOrder(OrderId.generate(),customerId);for(CartItemcartItem:cart.getItems()){order.addItem(cartItem.getProductId(),cartItem.getProductName(),cartItem.getPrice(),cartItem.getQuantity());}order.registerEvent(newOrderCreatedFromCartEvent(order.id,customerId,cart.getId()));returnorder;}}

14.2.2 不需要使用工厂的场景

// 简单对象:直接使用构造函数Moneyprice=Money.of("99.99");CustomerIdcustomerId=CustomerId.of("C001");OrderIdorderId=OrderId.generate();// 值对象:直接使用构造函数或静态工厂ShippingAddressaddress=newShippingAddress("上海市","浦东新区","张江镇","祖冲之路1234号","张三","13800138000");

14.3 工厂 vs 构造函数

14.3.1 对比分析

维度构造函数工厂方法工厂类
命名与类名相同自定义名称自定义名称
创建逻辑简单初始化中等复杂度高复杂度
返回类型固定为当前类可返回子类可返回任意类型
多种创建方式需要重载方法名区分方法名区分
位置类内部类内部或外部独立类
适用场景简单对象中等复杂对象复杂聚合

14.3.2 何时选择

【代码示例】

// 场景1:简单对象 → 构造函数Moneyprice=newMoney(newBigDecimal("99.99"),Currency.getInstance("CNY"));// 场景2:有语义的创建 → 静态工厂方法publicclassOrder{privateOrder(OrderIdid,CustomerIdcustomerId){...}publicstaticOrdercreate(CustomerIdcustomerId){...}publicstaticOrderreconstruct(OrderIdid,...){...}// 重建}// 场景3:复杂组装 → 工厂类publicclassOrderFactory{publicOrdercreateOrder(CreateOrderCommandcommand){// 复杂的组装逻辑}}// 场景4:需要外部依赖 → 工厂类 + 依赖注入@ServicepublicclassOrderFactory{@AutowiredprivatePricingServicepricingService;publicOrdercreateOrder(CreateOrderCommandcommand){// 可以使用定价服务}}

14.4 工厂 vs 依赖注入

14.4.1 区别与配合

【对比分析】

维度工厂依赖注入(DI)
目的创建业务对象注入服务依赖
创建时机业务驱动容器启动时
创建对象领域对象服务/组件
生命周期每次调用创建新实例通常单例
状态有状态(业务数据)无状态

【代码示例】

// ✅ 正确:工厂创建领域对象,DI注入服务@ServicepublicclassOrderFactory{// DI注入服务依赖privatefinalIdentityGeneratoridGenerator;privatefinalPricingServicepricingService;publicOrderFactory(IdentityGeneratoridGenerator,PricingServicepricingService){this.idGenerator=idGenerator;this.pricingService=pricingService;}// 工厂方法创建领域对象publicOrdercreateOrder(CreateOrderCommandcommand){OrderIdid=idGenerator.generateOrderId();CustomerIdcustomerId=Custo
http://www.jsqmd.com/news/945582/

相关文章:

  • 别再被AI检测卡脖子!8个免费降AI率工具盘点(2026最新亲测版)
  • 别再被Docker镜像下载卡住了!手把手教你配置阿里云镜像加速(CentOS 7实战)
  • Text2SQL 实战:让业务人员用自然语言查询数据库
  • 实战构建基于Hyperledger Fabric V2.5的企业级分布式溯源系统架构
  • BOBST 704-1123-04 PQ4882 PC板线轴
  • 别错过机会!2026实测好用的AI写作辅助软件|实测必入避坑版
  • Claude Code 完全实战指南 - 第五章:常用 Skill 推荐与最佳实践
  • Diff Checker:三分钟掌握文本差异对比的终极免费工具
  • OpenVoiceV2技术解析:语音克隆架构设计与实战指南
  • 毕业季福音:2026年亲测好用的8个免费降AI神器,附对比测评
  • [智能体-239]:MCP 给 LangChain 工具体系带来的增量价值(立足原有本地 Tool 机制做增量)
  • 利用LuaMacros与AutoHotkey将旧键盘改造为自定义宏键盘
  • 摆脱论文困扰! AI论文写作软件测评:2026最新推荐与对比
  • AFE断线检测的两种主流方案对比:LTC68xx电流源 vs MAX14920电阻分压,到底怎么选?
  • 暗影精灵8装Ubuntu双系统,我踩过的NVIDIA显卡坑和黑屏修复全记录
  • DIY三孔插座测试器:低成本电路设计与安全检测指南
  • BOBST C23-01 102022-0704141601控制器模块
  • HBase 与 Hadoop 安装与上手使用全指导
  • 2026年最新AI论文平台全攻略(含保姆级操作教程)
  • 51单片机RS485全双工通信仿真套件(Keil5源码+Proteus DSN+多场景例程)
  • 设计师正在消失?不,是“AI增强型设计师”正在诞生:基于172家企业的岗位能力图谱重构,含5级认证路径与真实项目交付SOP(绝密内参·首度解禁)
  • STC15单片机双串口通信实战:手把手教你配置串口2(附完整代码)
  • WSL 2内存占用太高?手把手教你用.wslconfig文件精细调优,告别卡顿
  • 设计走查表与设计还原度优化:像素级精准的工程实践
  • 仅限内部技术委员会解密:头部知识IP已用的AI播客灰度发布模型(含Latency<800ms实测数据)
  • 工业应用需高强度耐磨合金?揭秘高品质Inconel 718生产厂家的实力 - 品牌2026
  • 2026最新!8款论文降AI率工具实测合集,建议收藏(含免费版)
  • 库存告急怎么办?拥有大库存量的Inconel 718厂商推荐清单 - 品牌2026
  • [智能体-240]:LangChain实现MCP工具调用的代码示例(MCP client端)
  • 【权威认证】工信部信创工作组推荐方案:AI工具与智能勋章融合的6层可信架构标准