在电商应用开发中,商品管理、购物车、订单处理等模块往往涉及复杂业务逻辑。easy-model 的模型驱动架构能有效组织这些领域知识,提升代码可维护性。本文通过实际用例展示如何使用 easy-model 实现电商领域的领域驱动开发。
商品管理模型
商品是电商的核心领域。我们可以创建一个 ProductModel 来封装商品状态和业务逻辑:
import { useModel } from "easy-model";
class ProductModel {
product = {
id: "",
name: "",
price: 0,
stock: 0,
category: ""
};
constructor(initialProduct: typeof this.product) {
this.product = initialProduct;
}
updateStock(newStock: number) {
if (newStock < 0) throw new Error("库存不能为负");
this.product.stock = newStock;
}
isAvailable() {
return this.product.stock > 0;
}
applyDiscount(discountPercent: number) {
this.product.price *= (1 - discountPercent / 100);
}
}
function ProductCard({ productId }: { productId: string }) {
const productModel = useModel(ProductModel, [{
id: productId,
name: "iPhone 15",
price: 5999,
stock: 10,
category: "电子产品"
}]);
return (
<div>
<h3>{productModel.product.name}</h3>
<p>价格: ¥{productModel.product.price}</p>
<p>库存: {productModel.product.stock}</p>
<p>状态: {productModel.isAvailable() ? "有货" : "缺货"}</p>
<button onClick={() => productModel.updateStock(productModel.product.stock - 1)}>
购买
</button>
</div>
);
}
这个模型封装了商品的业务规则,如库存管理、折扣应用等。领域逻辑集中,避免了在组件中散布业务代码。
购物车共享状态
电商应用中,购物车需要在多个组件间共享。easy-model 天然支持按用户分组的实例缓存:
import { useModel } from "easy-model";
class CartModel {
items: Array<{ productId: string; quantity: number }> = [];
userId: string;
constructor(userId: string) {
this.userId = userId;
}
addItem(productId: string, quantity: number) {
const existing = this.items.find(item => item.productId === productId);
if (existing) {
existing.quantity += quantity;
} else {
this.items.push({ productId, quantity });
}
}
getTotalItems() {
return this.items.reduce((sum, item) => sum + item.quantity, 0);
}
}
const CartProvider = provide(CartModel);
function CartIcon() {
const cart = useModel(CartProvider, ["user123"]);
return <div>购物车 ({cart.getTotalItems()})</div>;
}
function AddToCartButton({ productId }: { productId: string }) {
const cart = useModel(CartProvider, ["user123"]);
return (
<button onClick={() => cart.addItem(productId, 1)}>
加入购物车
</button>
);
}
通过 useModel,不同组件共享同一购物车实例,按用户ID分组,确保数据一致性。
订单异步处理
订单提交涉及异步操作。easy-model 的 @loader.load 装饰器简化加载状态管理:
import { loader, useLoader, useModel } from "easy-model";
class OrderModel {
order = { id: "", status: "pending", items: [] };
constructor(orderId: string) {
this.order.id = orderId;
}
@loader.load(true)
async submitOrder() {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 2000));
this.order.status = "confirmed";
}
}
function OrderForm() {
const orderModel = useModel(OrderModel, ["order123"]);
const { isLoading } = useLoader();
return (
<div>
<p>订单状态: {orderModel.order.status}</p>
<button
onClick={() => orderModel.submitOrder()}
disabled={isLoading}
>
{isLoading ? "提交中..." : "提交订单"}
</button>
</div>
);
}
useLoader 自动跟踪异步方法状态,无需手动管理 loading 布尔值。
测试驱动开发
easy-model 的模型类易于测试,确保业务逻辑正确:
import { describe, it, expect } from "vitest";
describe("ProductModel", () => {
it("should update stock correctly", () => {
const model = new ProductModel({
id: "1",
name: "Test",
price: 100,
stock: 5,
category: "Test",
});
model.updateStock(3);
expect(model.product.stock).toBe(3);
});
it("should throw on negative stock", () => {
const model = new ProductModel({
id: "1",
name: "Test",
price: 100,
stock: 5,
category: "Test",
});
expect(() => model.updateStock(-1)).toThrow();
});
});
单元测试覆盖业务规则,提升代码质量。
总结
easy-model 在电商应用中展现出强大实力:模型封装领域逻辑、provide 支持状态共享、@loader.load 简化异步处理。结合 Vitest 测试,确保高质量交付。试试 easy-model,让电商开发更优雅!
项目地址:GitHub