Java订单管理核心是建模、状态机与CRUD设计:金额用BigDecimal、状态用枚举约束;Order与OrderItem分离;状态迁移通过枚举内置规则校验;内存服务用ConcurrentHashMap实现,注重流程拆分与扩展性。

Java中开发简单订单管理程序,核心不是堆砌框架,而是理清三个关键点:数据模型怎么建、状态流转怎么控、增删改查怎么稳。用纯Java(不依赖Spring Boot)也能跑通全流程,适合教学、练手或轻量后台。
订单与商品类怎么设计才不踩坑
很多初学者直接用String存金额、用int存状态,后续扩展和精度计算立刻出问题。必须用BigDecimal处理金额,用枚举约束状态。
常见错误现象:0.1 + 0.2 == 0.3返回false;订单状态被随意赋值如order.setStatus(99)导致逻辑错乱。
-
Order类至少包含:orderId(String或Long)、customerId、orderDate(LocalDateTime)、totalAmount(BigDecimal)、status(OrderStatus枚举) -
OrderItem类不要嵌套在Order里,单独建类并用List关联,方便后续拆单、退货 - 避免在
Order中直接持有Product对象(易引发循环引用),只存productId和快照字段如itemName、itemPrice
订单状态机用if-else还是枚举+方法
用一堆if (status == 1) {...} else if (status == 2) {...}写法,在增加“已发货”“部分退款”等状态后会迅速失控。推荐用枚举内置状态迁移规则。
立即学习“Java免费学习笔记(深入)”;
使用场景:用户下单后不能取消已支付订单,已发货订单不能修改地址——这些约束必须在代码里强制体现,而不是靠文档或注释。
- 定义
enum OrderStatus,每个枚举值带canTransitionTo(Set方法) - 状态变更统一走
order.transitionTo(OrderStatus.PAID),内部校验是否允许跳转 - 不要把数据库更新和状态校验混在一个方法里,先校验再
updateStatusInDB(),失败时能明确抛出IllegalStateException
内存版订单服务怎么支持基本CRUD
不接数据库也能验证业务逻辑是否自洽。用ConcurrentHashMap模拟存储,重点是把“查订单→校验权限→执行操作→持久化”流程拆清楚。
性能影响:纯内存操作毫秒级,但ConcurrentHashMap的computeIfAbsent和replace要慎用,避免锁竞争;并发下单时orderId生成必须全局唯一(别用new Random().nextInt())。
-
orderId建议用UUID.randomUUID().toString().replace("-", "")或时间戳+自增序列 -
queryByCustomerId(String customerId)返回unmodifiableList,防止外部修改影响内部状态 - 删除订单不是真删,统一走
markAsDeleted()设isDeleted = true,保持审计线索
public class InMemoryOrderService {
private final Map orders = new ConcurrentHashMap<>();
public Order createOrder(Order order) {
if (order.getTotalAmount().compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Total amount must be positive");
}
order.setStatus(OrderStatus.CREATED);
order.setOrderDate(LocalDateTime.now());
orders.put(order.getOrderId(), order);
return order;
}
public Optional findById(String orderId) {
return Optional.ofNullable(orders.get(orderId));
}
}
真正难的不是写完这几十行代码,而是想清楚:如果下周要加“优惠券抵扣”“多仓库分单”,现在这个Order类要不要拆?状态枚举要不要分“前台可见状态”和“系统内部状态”?这些设计决策比语法细节重要得多。










