java中设计思想和架构理念
目录
java中设计思想和架构理念
Java生态中有多种类似于DDD的设计思想和架构理念,它们从不同角度解决软件复杂性问题。以下是主要的几种:
1. 六边形架构(Hexagonal Architecture)/ 端口适配器架构
核心思想
应用为核心,外部依赖为可替换的适配器
java
// 端口(接口)定义在应用内部
public interface OrderRepository { // primary port
Order findById(OrderId id);
void save(Order order);
}
public interface PaymentService { // secondary port
PaymentResult processPayment(PaymentRequest request);
}
// 适配器实现端口
@Repository
public class OrderRepositoryAdapter implements OrderRepository {
// 实现数据库操作
}
@Component
public class PayPalAdapter implements PaymentService {
// 实现PayPal支付
}
@Component
public class StripeAdapter implements PaymentService {
// 实现Stripe支付
}
与DDD的关系
- 互补关系:六边形架构解决技术依赖问题,DDD解决业务建模问题
- 常结合使用:DDD的领域层位于六边形架构的核心
2. 清洁架构(Clean Architecture)
核心思想
依赖规则:内层不依赖外层,依赖方向指向中心
java
// 实体层(最内层)
public class Order {
private OrderId id;
private Money amount;
public boolean canBeCancelled() {
return amount.getValue().compareTo(BigDecimal.ZERO) > 0;
}
}
// 用例层
public class CancelOrderUseCase {
private final OrderRepository orderRepository;
public CancelOrderUseCase(OrderRepository repository) {
this.orderRepository = repository;
}
public void execute(CancelOrderCommand command) {
Order order = orderRepository.findById(command.getOrderId());
if (order.canBeCancelled()) {
order.cancel();
orderRepository.save(order);
}
}
}
// 接口适配器层
@RestController
public class OrderController {
private final CancelOrderUseCase cancelOrderUseCase;
@PostMapping("/orders/{id}/cancel")
public void cancelOrder(@PathVariable String id) {
cancelOrderUseCase.execute(new CancelOrderCommand(id));
}
}
// 框架层(最外层)
@Repository
public class OrderRepositoryImpl implements OrderRepository {
// JPA实现
}
与DDD的对比
维度 | 清洁架构 | DDD |
---|---|---|
重点 | 依赖关系管理 | 业务建模和通用语言 |
层次 | 同心圆层次 | 水平分层 |
核心 | 用例和实体 | 聚合和领域服务 |
3. CQRS(命令查询职责分离)
核心思想
读写分离,不同的模型处理命令和查询
java
// 命令端(写操作)
@Service
@Transactional
public class OrderCommandService {
public OrderId createOrder(CreateOrderCommand command) {
Order order = Order.create(command);
orderRepository.save(order);
// 发布领域事件
eventPublisher.publish(new OrderCreatedEvent(order.getId()));
return order.getId();
}
}
// 查询端(读操作)
@Service
@Transactional(readOnly = true)
public class OrderQueryService {
public OrderView getOrderView(OrderId id) {
return orderViewRepository.findById(id);
}
public List<OrderSummary> getOrderSummaries(OrderQuery query) {
return orderSummaryRepository.findByCriteria(query);
}
}
// 不同的数据模型
// 命令模型 - 丰富的领域模型
public class Order {
// 包含业务逻辑和行为
}
// 查询模型 - 简单的DTO
public class OrderView {
private String orderId;
private String status;
private BigDecimal totalAmount;
// 只有getter方法,无行为
}
与DDD的结合
- 增强DDD:CQRS可以解决DDD中查询操作的性能问题
- 事件溯源:常与Event Sourcing结合,实现完整的审计追踪
4. 事件驱动架构(Event-Driven Architecture)
核心思想
通过事件进行组件间通信,实现松耦合
java
// 领域事件
public class OrderCreatedEvent implements DomainEvent {
private final OrderId orderId;
private final LocalDateTime occurredOn;
public OrderCreatedEvent(OrderId orderId) {
this.orderId = orderId;
this.occurredOn = LocalDateTime.now();
}
}
// 事件处理器
@Component
public class OrderCreatedEventHandler {
@EventListener
public void handle(OrderCreatedEvent event) {
// 发送通知
notificationService.sendOrderConfirmation(event.getOrderId());
// 更新读模型
orderReadModelUpdater.update(event.getOrderId());
// 触发后续业务流程
inventoryService.reserveStock(event.getOrderId());
}
}
// 事件发布
public class Order {
public static Order create(CreateOrderCommand command) {
Order order = new Order();
// 初始化逻辑
order.registerEvent(new OrderCreatedEvent(order.getId()));
return order;
}
}
5. 微服务架构(Microservices Architecture)
核心思想
单一职责,独立部署,围绕业务能力组织
java
// 用户服务
@Service
public class UserService {
public UserDTO getUserWithOrders(Long userId) {
User user = userRepository.findById(userId);
// 调用订单服务(跨服务调用)
List<OrderDTO> orders = orderServiceClient.getUserOrders(userId);
return UserDTO.withOrders(user, orders);
}
}
// 订单服务
@Service
public class OrderService {
public OrderDTO createOrder(CreateOrderRequest request) {
// 调用用户服务验证用户
UserInfo user = userServiceClient.getUserInfo(request.getUserId());
if (!user.isActive()) {
throw new IllegalStateException("用户状态异常");
}
Order order = Order.create(request, user);
return orderRepository.save(order);
}
}
与DDD的关系
- 边界对齐:微服务边界应该与DDD的限界上下文对齐
- 协同工作:DDD帮助识别微服务的合理边界
6. 面向切面编程(AOP)
核心思想
横切关注点分离
java
// 切面定义
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example..service.*.*(..))")
public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
log.info("开始执行方法: {}", methodName);
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
log.info("方法执行完成: {}, 耗时: {}ms", methodName, executionTime);
return result;
}
}
// 领域服务(无需修改)
@Service
public class OrderService {
public Order createOrder(CreateOrderCommand command) {
// 业务逻辑,日志通过AOP自动添加
return orderRepository.save(order);
}
}
7. 战略设计模式
核心思想
通过模式语言解决大型系统复杂度
java
// 限界上下文映射
public interface ContextMapping {
// 客户上下文
interface CustomerContext {
Customer findCustomer(CustomerId id);
}
// 订单上下文
interface OrderContext {
Order createOrder(CustomerId customerId, OrderItems items);
}
// 防腐层(Anti-Corruption Layer)
@Component
public class OrderContextACL {
private final CustomerContext customerContext;
public CustomerInfo getCustomerInfo(CustomerId id) {
Customer customer = customerContext.findCustomer(id);
return convertToOrderContextModel(customer);
}
private CustomerInfo convertToOrderContextModel(Customer customer) {
// 转换逻辑,防止外部模型污染当前上下文
return new CustomerInfo(customer.getId(), customer.getName());
}
}
}
8. 数据网格(Data Mesh)
核心思想
数据作为产品,领域导向的数据所有权
java
// 领域数据产品
@Component
public class OrderDataProduct {
public OrderAnalytics getOrderAnalytics(TimeRange range) {
// 领域负责自己的数据产品
return orderRepository.getAnalytics(range);
}
public void publishOrderEvents(OrderEvent event) {
// 发布数据变更事件
eventStream.publish(event);
}
}
// 数据消费者
@Component
public class RecommendationService {
public List<Product> getRecommendations(UserId userId) {
// 消费其他领域的数据产品
OrderHistory history = orderDataProduct.getUserOrderHistory(userId);
return calculateRecommendations(history);
}
}
各种架构思想的适用场景对比
架构思想 | 适用场景 | 核心价值 | 与DDD关系 |
---|---|---|---|
六边形架构 | 需要技术隔离的应用 | 解耦技术依赖 | 基础设施实现 |
清洁架构 | 长期维护的大型系统 | 依赖管理 | 层次细化 |
CQRS | 读写负载差异大的系统 | 性能优化 | 查询端补充 |
事件驱动 | 异步、松耦合系统 | 响应性和弹性 | 领域事件扩展 |
微服务 | 大型分布式系统 | 独立部署和扩展 | 限界上下文对齐 |
AOP | 横切关注点处理 | 代码复用和整洁 | 技术关注点分离 |
战略设计 | 复杂领域建模 | 大型系统分解 | DDD的核心部分 |
数据网格 | 大数据和数据分析 | 数据民主化 | 数据领域化 |
实际项目中的组合使用
java
// 综合示例:DDD + 清洁架构 + CQRS + 事件驱动
@ApplicationService // 清洁架构的用例层
public class OrderApplicationService {
@Transactional
public OrderId placeOrder(PlaceOrderCommand command) {
// DDD领域逻辑
Order order = Order.place(command);
orderRepository.save(order);
// 事件驱动
eventPublisher.publish(new OrderPlacedEvent(order.getId()));
return order.getId();
}
}
@QueryService // CQRS查询端
@Transactional(readOnly = true)
public class OrderQueryService {
public OrderView getOrderView(OrderId id) {
return orderViewRepository.findById(id);
}
}
@RestController // 六边形架构的适配器
public class OrderController {
@PostMapping("/orders")
public ResponseEntity<OrderId> placeOrder(@RequestBody PlaceOrderRequest request) {
OrderId orderId = orderApplicationService.placeOrder(toCommand(request));
return ResponseEntity.ok(orderId);
}
}
选择建议
- 从简单开始:先采用分层架构,随着复杂度增加引入其他模式
- 按需选择:根据具体业务需求和技术约束选择合适的架构组合
- 渐进演进:不要一开始就过度设计,根据项目发展逐步引入合适的架构
- 团队能力:考虑团队的技术能力和业务理解水平
这些架构思想不是互斥的,在实际项目中往往会根据具体情况组合使用,形成最适合当前项目的架构方案。