--- paths: - "**/*.java" --- # Java 模式 > 本文档扩展了 [common/patterns.md](../common/patterns.md) 中的内容,增加了 Java 特有的部分。 ## 仓储模式 将数据访问封装在接口之后: ```java public interface OrderRepository { Optional findById(Long id); List findAll(); Order save(Order order); void deleteById(Long id); } ``` 具体的实现类处理存储细节(JPA、JDBC、用于测试的内存存储等)。 ## 服务层 业务逻辑放在服务类中;保持控制器和仓储层的精简: ```java public class OrderService { private final OrderRepository orderRepository; private final PaymentGateway paymentGateway; public OrderService(OrderRepository orderRepository, PaymentGateway paymentGateway) { this.orderRepository = orderRepository; this.paymentGateway = paymentGateway; } public OrderSummary placeOrder(CreateOrderRequest request) { var order = Order.from(request); paymentGateway.charge(order.total()); var saved = orderRepository.save(order); return OrderSummary.from(saved); } } ``` ## 构造函数注入 始终使用构造函数注入 —— 绝不使用字段注入: ```java // GOOD — constructor injection (testable, immutable) public class NotificationService { private final EmailSender emailSender; public NotificationService(EmailSender emailSender) { this.emailSender = emailSender; } } // BAD — field injection (untestable without reflection, requires framework magic) public class NotificationService { @Inject // or @Autowired private EmailSender emailSender; } ``` ## DTO 映射 使用记录(record)作为 DTO。在服务层/控制器边界进行映射: ```java public record OrderResponse(Long id, String customer, BigDecimal total) { public static OrderResponse from(Order order) { return new OrderResponse(order.getId(), order.getCustomerName(), order.getTotal()); } } ``` ## 建造者模式 用于具有多个可选参数的对象: ```java public class SearchCriteria { private final String query; private final int page; private final int size; private final String sortBy; private SearchCriteria(Builder builder) { this.query = builder.query; this.page = builder.page; this.size = builder.size; this.sortBy = builder.sortBy; } public static class Builder { private String query = ""; private int page = 0; private int size = 20; private String sortBy = "id"; public Builder query(String query) { this.query = query; return this; } public Builder page(int page) { this.page = page; return this; } public Builder size(int size) { this.size = size; return this; } public Builder sortBy(String sortBy) { this.sortBy = sortBy; return this; } public SearchCriteria build() { return new SearchCriteria(this); } } } ``` ## 使用密封类型构建领域模型 ```java public sealed interface PaymentResult permits PaymentSuccess, PaymentFailure { record PaymentSuccess(String transactionId, BigDecimal amount) implements PaymentResult {} record PaymentFailure(String errorCode, String message) implements PaymentResult {} } // Exhaustive handling (Java 21+) String message = switch (result) { case PaymentSuccess s -> "Paid: " + s.transactionId(); case PaymentFailure f -> "Failed: " + f.errorCode(); }; ``` ## API 响应封装 统一的 API 响应格式: ```java public record ApiResponse(boolean success, T data, String error) { public static ApiResponse ok(T data) { return new ApiResponse<>(true, data, null); } public static ApiResponse error(String message) { return new ApiResponse<>(false, null, message); } } ``` ## 参考 有关 Spring Boot 架构模式,请参见技能:`springboot-patterns`。 有关实体设计和查询优化,请参见技能:`jpa-patterns`。