雷州市网站建设,长沙网络seo公司助企业突破,wordpress更新要ftp,建立网站时服务器的基本配置有哪些DDD 是一套 应对复杂业务系统 的设计方法论#xff0c;核心是 让代码直接映射业务逻辑#xff0c;避免技术实现与业务需求脱节。 关键区别#xff1a;
传统开发#xff1a;根据数据库表写 CRUD#xff08;技术驱动#xff09;。DDD#xff1a;根据业务行为建模#xf…DDD 是一套 应对复杂业务系统 的设计方法论核心是 让代码直接映射业务逻辑避免技术实现与业务需求脱节。 关键区别
传统开发根据数据库表写 CRUD技术驱动。DDD根据业务行为建模业务驱动。
举例
传统方式设计 orders 表 → 写 OrderDAO → 实现增删改查。DDD 方式先分析业务如何描述“订单”如“下单”、“取消”、“支付超时”→ 再建模为 Order 对象的行为。 贫血模型与充血模型
本质特征
特征贫血模型充血模型业务逻辑存放位置Service层领域对象Entity/Value Object内部领域对象职责仅作为数据载体DTO封装数据和行为代码表现大量Getter/Setter无业务方法包含业务方法适用场景简单CRUD系统复杂业务系统DDD推荐
代码实现对比
贫血模型实现
Order 只是数据的容器业务逻辑散落在 Service 中。当业务复杂时Service 会变成“上帝类”God Class。
// 1. 贫血的Order类仅有数据
public class Order {private String orderId;private String productId;private int quantity;private String status;// 只有Getter/Setter无业务逻辑public String getOrderId() { return orderId; }public void setOrderId(String orderId) { this.orderId orderId; }// 其他Getter/Setter省略...
}// 2. 业务逻辑全在Service中
Service
public class OrderService {public void createOrder(String productId, int quantity) {Order order new Order();order.setOrderId(UUID.randomUUID().toString());order.setProductId(productId);order.setQuantity(quantity);order.setStatus(CREATED);// 校验逻辑也在Service中if (quantity 0) {throw new IllegalArgumentException(Quantity must be positive);}orderRepository.save(order);}
}充血模型实现
Order 自己负责业务规则如创建校验、状态转换。业务逻辑高内聚Service层变薄。
// 1. 充血的Order类封装数据和行为
public class Order {private String orderId;private String productId;private int quantity;private OrderStatus status; // 枚举// 私有构造方法强制通过工厂方法创建private Order(String productId, int quantity) {this.orderId UUID.randomUUID().toString();this.productId productId;this.quantity quantity;this.status OrderStatus.CREATED;}// 静态工厂方法封装创建逻辑public static Order create(String productId, int quantity) {if (quantity 0) {throw new IllegalArgumentException(Quantity must be positive);}return new Order(productId, quantity);}// 领域行为public void cancel() {if (this.status OrderStatus.PAID) {throw new IllegalStateException(Paid order cannot be cancelled);}this.status OrderStatus.CANCELLED;}
}// 2. 应用层Service仅协调流程
Service
public class OrderAppService {public void createOrder(String productId, int quantity) {Order order Order.create(productId, quantity); // 调用领域对象orderRepository.save(order);}
}DDD实战
架构图 架构设计
src/
├── presentation/ # 用户接口层
├── application/ # 应用层
├── domain/ # 领域层
│ ├── model/ # 领域模型实体、值对象等
│ └── repository/ # 仓储接口
└── infrastructure/ # 基础设施层简单实现代码示例
(1) 用户接口层Presentation Layer
处理HTTP请求接收用户输入。
// presentation/OrderController.java
RestController
RequestMapping(/orders)
public class OrderController {private final OrderAppService orderAppService; // 依赖应用层PostMappingpublic ResponseEntityString createOrder(RequestBody CreateOrderRequest request) {orderAppService.createOrder(request.toCommand()); // 转换为命令对象return ResponseEntity.ok(Order created);}
}// DTO用户请求参数
public class CreateOrderRequest {private String productId;private int quantity;// 转换为应用层命令对象public CreateOrderCommand toCommand() {return new CreateOrderCommand(productId, quantity);}
}(2) 应用层Application Layer
协调领域对象完成用例不包含业务逻辑。
// application/OrderAppService.java
Service
public class OrderAppService {private final OrderRepository orderRepository; // 依赖领域层仓储public void createOrder(CreateOrderCommand command) {// 1. 调用领域层创建订单Order order Order.create(command.getProductId(), command.getQuantity());// 2. 通过仓储保存聚合根orderRepository.save(order);// 3. 可发布领域事件此处省略}
}// 应用层命令对象
public class CreateOrderCommand {private String productId;private int quantity;// 构造方法、getter省略...
}(3) 领域层Domain Layer
核心业务逻辑包含实体、值对象、仓储接口等。
3.1 实体Entity与聚合根
// domain/model/Order.java
public class Order {private String orderId; // 唯一标识private String productId;private int quantity;private OrderStatus status; // 枚举CREATED, PAID, CANCELLED等// 私有构造方法强制通过工厂方法创建private Order(String productId, int quantity) {this.orderId UUID.randomUUID().toString();this.productId productId;this.quantity quantity;this.status OrderStatus.CREATED;}// 工厂方法封装创建逻辑public static Order create(String productId, int quantity) {if (quantity 0) {throw new IllegalArgumentException(Quantity must be positive);}return new Order(productId, quantity);}// 领域行为public void cancel() {this.status OrderStatus.CANCELLED;}
}3.2 仓储接口Repository
// domain/repository/OrderRepository.java
public interface OrderRepository {void save(Order order);// 其他查询方法省略...
}(4) 基础设施层Infrastructure Layer
实现领域层定义的仓储接口如数据库操作。
// infrastructure/persistence/OrderRepositoryImpl.java
Repository
public class OrderRepositoryImpl implements OrderRepository {// 模拟数据库实际可用JPA/MyBatis等private MapString, Order orders new HashMap();Overridepublic void save(Order order) {orders.put(order.getOrderId(), order);System.out.println(Order saved: order.getOrderId());}
}调用流程图 对比传统CRUD
DDD传统CRUD先设计Order的行为方法直接操作orders表业务逻辑在领域层业务逻辑散落在Service中通过聚合根保证一致性需手动校验外键约束
充血模型特点
禁止Setter通过构造方法或工厂方法创建对象。领域方法命名使用业务语言如 cancel() 而非 setStatus(CANCELLED)。避免“贫血”的充血模型 错误示例在 Order 中加了方法但核心逻辑仍在Service中。 常见误区
❌ 认为充血模型等于“把所有代码塞进Entity” 跨聚合逻辑应放在领域服务Domain Service中。 ❌ 忽视聚合根的一致性边界 例如订单和库存属于不同聚合不能直接在 Order 中修改库存应通过领域事件解耦。