商品与库存应绑定为Product类的int stock字段,扣减必须通过原子化decreaseStock()方法校验;订单创建需先扣库存再生成订单,用HashMap存订单以支持O(1)查询。

Java 开发简单商城原型,核心不在于堆砌框架,而在于理清 用户→商品→订单→库存 这四者间的数据流向和状态约束。用纯 Java(JDK 8+)+ 内存模拟 + 控制台交互,300 行内就能跑通主干流程。
怎么设计商品与库存的绑定关系
别一上来就建 Product 和 Inventory 两张表——内存原型里,直接让 Product 类持有一个 int stock 字段更轻量、更可控。关键点是:库存变更必须原子化,避免超卖。
- 所有库存扣减必须走
decreaseStock(int amount)方法,内部用if (stock >= amount) { stock -= amount; return true; }判断 - 不要在业务逻辑里直接写
product.stock--,这会绕过校验 - 如果后续要加分布式支持,这里就是上
Redis Lua或数据库UPDATE ... WHERE stock >= ?的锚点
订单创建时如何保证数据一致性
控制台下单看似简单,但“查库存→扣库存→生成订单”三步若不同步,必然出现超卖。内存原型中用同步块 + 状态检查即可解决,无需引入事务管理器。
public Order createOrder(String userId, String productId, int quantity) {
Product product = productMap.get(productId);
if (product == null || !product.decreaseStock(quantity)) {
return null; // 库存不足,拒绝下单
}
Order order = new Order(orderIdGenerator++, userId, productId, quantity);
orderMap.put(order.getId(), order);
return order;
}
- 注意顺序:先
decreaseStock()成功,再新建Order实例 - 返回
null比抛异常更适合原型阶段,方便控制台快速反馈 -
orderIdGenerator用AtomicLong更安全,但单线程控制台下用int足够
为什么不用 ArrayList 存订单而用 HashMap
因为真实查询场景中,90% 的订单操作基于 id:查单、取消、发货。用 HashMap 直接 get(id) 是 O(1),而 ArrayList 遍历是 O(n)。原型虽小,索引意识不能丢。
立即学习“Java免费学习笔记(深入)”;
- 订单列表展示可用
orderMap.values().stream().collect(Collectors.toList())临时转成 List - 用户维度查单可额外维护一个
Map,但原型阶段先不做,避免过早复杂化> userOrders - 键名建议用字符串(如
"ORD_" + id),方便未来对接 JSON 或 HTTP 接口
真正难的不是写完能下单,而是当你要加「购物车合并下单」「订单超时回滚库存」「用户余额扣款」时,发现原来把库存扣减逻辑散落在三个地方——所以从第一行代码起,就要把「状态变更」封装成方法,而不是写三次 product.stock -= x。










