在.NET Core中實現領域驅動設計(DDD):電商訂單管理示例
領域驅動設計(DDD)是一種通過深入理解業(yè)務領域來指導系統設計的架構模式。在.NET Core中應用DDD的思想,可以幫助開發(fā)者在復雜的業(yè)務場景下構建高內聚、低耦合的系統架構。本篇文章將通過一個電商系統中的訂單管理模塊為例,展示如何在.NET Core中實現DDD,深入理解聚合根、實體、值對象、應用層、領域服務等DDD核心概念。
一、項目背景
假設我們正在構建一個電商系統,其中最基礎的業(yè)務對象之一就是“訂單”。訂單管理包括多個操作,如創(chuàng)建訂單、添加訂單項、更新訂單狀態(tài)等。為了使系統易于維護和擴展,我們將使用領域驅動設計(DDD)來組織代碼。具體地,我們會使用以下核心概念來構建這一部分功能:
- 領域模型(Domain Model):包括訂單(Order)、訂單項(OrderItem)等實體。
- 聚合根(Aggregate Root):訂單(Order)是聚合根,負責管理訂單項。
- 值對象(Value Object):可能涉及到一些不可變的對象,如貨幣金額、地址等(本示例中未深入展開)。
- 領域服務(Domain Service):處理與業(yè)務邏輯相關的操作。
- 應用層(Application Layer):協調領域服務和外部資源(如數據庫)的交互。
- 倉儲(Repository):負責持久化和加載領域對象。
- Web層(Web Layer):提供API接口供外部系統訪問。
目錄結構
首先,為了組織好代碼,我們可以遵循以下推薦的項目結構:
ECommerceApp/
│
├── Application/ // 用于封裝應用程序服務層
│ └── OrderService.cs // 業(yè)務邏輯服務層
│
├── Domain/ // 包含領域模型和業(yè)務規(guī)則
│ ├── Order.cs // 訂單實體
│ ├── OrderItem.cs // 訂單項實體
│ ├── IOrderRepository.cs // 訂單倉儲接口
│ └── OrderStatus.cs // 訂單狀態(tài)(枚舉)
│
├── Infrastructure/ // 數據訪問層(實現倉儲接口)
│ └── OrderRepository.cs // 訂單倉儲實現
│
├── Web/ // ASP.NET Core 控制器和API層
│ └── OrderController.cs // 控制器
│
└── ECommerceApp.sln // 解決方案文件
二、領域模型(Domain)
在DDD中,領域模型是應用程序的核心,它定義了業(yè)務邏輯和業(yè)務規(guī)則。我們將在這一層實現訂單實體(Order)、訂單項實體(OrderItem)、訂單狀態(tài)枚舉(OrderStatus)以及訂單倉儲接口(IOrderRepository)。
1. 訂單實體(Order)
訂單實體(Order)是一個聚合根,負責管理訂單的各個方面,比如訂單項的添加和訂單狀態(tài)的變更。
namespace ECommerceApp.Domain
{
public class Order
{
public int Id { get; private set; }
public string CustomerName { get; private set; }
public OrderStatus Status { get; private set; }
public List<OrderItem> OrderItems { get; private set; }
// 構造函數:訂單一旦創(chuàng)建,不能更改訂單項的數量
public Order(string customerName)
{
CustomerName = customerName;
Status = OrderStatus.Pending;
OrderItems = new List<OrderItem>();
}
// 添加訂單項:確保訂單項的數量大于0
public void AddOrderItem(string productName, decimal price, int quantity)
{
if (quantity <= 0) throw new InvalidOperationException("Order item quantity must be greater than zero.");
OrderItems.Add(new OrderItem(productName, price, quantity));
}
// 改變訂單狀態(tài)
public void ChangeStatus(OrderStatus newStatus)
{
Status = newStatus;
}
}
}
2. 訂單項實體(OrderItem)
訂單項(OrderItem)是訂單聚合內的一個實體,表示一個具體的商品項,包括商品名稱、價格和數量。
namespace ECommerceApp.Domain
{
public class OrderItem
{
public string ProductName { get; private set; }
public decimal Price { get; private set; }
public int Quantity { get; private set; }
public OrderItem(string productName, decimal price, int quantity)
{
ProductName = productName;
Price = price;
Quantity = quantity;
}
}
}
3. 訂單狀態(tài)(OrderStatus)
訂單狀態(tài)(OrderStatus)是一個枚舉,表示訂單的不同生命周期狀態(tài)。
namespace ECommerceApp.Domain
{
public enum OrderStatus
{
Pending,
Paid,
Shipped,
Delivered
}
}
4. 訂單倉儲接口(IOrderRepository)
倉儲接口(IOrderRepository)用于從數據存儲中加載和保存訂單對象。
namespace ECommerceApp.Domain
{
public interface IOrderRepository
{
Task<Order> GetOrderByIdAsync(int orderId);
Task AddAsync(Order order);
Task SaveAsync();
}
}
三、應用層(Application)
應用層負責協調領域模型和外部系統的交互。它通常包含一些業(yè)務邏輯服務,在此層中不會包含復雜的領域邏輯。
訂單服務(OrderService)
namespace ECommerceApp.Application
{
public class OrderService
{
private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
// 創(chuàng)建訂單并添加訂單項
public async Task CreateOrderAsync(string customerName, List<(string productName, decimal price, int quantity)> orderItems)
{
var order = new Order(customerName);
foreach (var item in orderItems)
{
order.AddOrderItem(item.productName, item.price, item.quantity);
}
await _orderRepository.AddAsync(order);
await _orderRepository.SaveAsync();
}
// 改變訂單狀態(tài)
public async Task ChangeOrderStatusAsync(int orderId, OrderStatus newStatus)
{
var order = await _orderRepository.GetOrderByIdAsync(orderId);
if (order == null) throw new Exception("Order not found.");
order.ChangeStatus(newStatus);
await _orderRepository.SaveAsync();
}
}
}
四、基礎設施層(Infrastructure)
基礎設施層提供具體的實現,例如數據存儲操作、第三方API集成等。在這里,我們實現了訂單倉儲的內存模擬版本。
訂單倉儲實現(OrderRepository)
namespace ECommerceApp.Infrastructure
{
public class OrderRepository : IOrderRepository
{
private readonly List<Order> _orders = new List<Order>();
public async Task<Order> GetOrderByIdAsync(int orderId)
{
return await Task.FromResult(_orders.FirstOrDefault(o => o.Id == orderId));
}
public async Task AddAsync(Order order)
{
order = new Order(order.CustomerName); // Simulate creating an ID or other operations
_orders.Add(order);
await Task.CompletedTask;
}
public async Task SaveAsync()
{
// In a real application, you would persist changes to a database here
await Task.CompletedTask;
}
}
}
五、Web層(Web)
在ASP.NET Core的Web層中,我們通過控制器暴露API接口,允許外部調用應用程序服務。
訂單控制器(OrderController)
using Microsoft.AspNetCore.Mvc;
using ECommerceApp.Application;
namespace ECommerceApp.Web.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class OrderController : ControllerBase
{
private readonly OrderService _orderService;
public OrderController(OrderService orderService)
{
_orderService = orderService;
}
// 創(chuàng)建訂單
[HttpPost]
public async Task<IActionResult> CreateOrder([FromBody] CreateOrderRequest request)
{
await _orderService.CreateOrderAsync(request.CustomerName, request.OrderItems);
return Ok();
}
// 修改訂單狀態(tài)
[HttpPut("{orderId}/status")]
public async Task<IActionResult> ChangeStatus(int orderId, [FromBody] ChangeStatusRequest request)
{
await _orderService.ChangeOrderStatusAsync(orderId, request.NewStatus);
return Ok();
}
}
public class CreateOrderRequest
{
public string CustomerName { get; set; }
public List<(string productName, decimal price, int quantity)> OrderItems { get; set; }
}
public class ChangeStatusRequest
{
public OrderStatus NewStatus { get; set; }
}
}
六、總結
通過本示例,我們展示了如何在.NET Core中實現一個電商系統的訂單管理部分,并采用DDD的設計理念。具體包括:
- 領域層:實現了訂單(Order)、訂單項(OrderItem)、訂單狀態(tài)(OrderStatus)等領域對象和業(yè)務規(guī)則。
- 應用層:通過
OrderService提供業(yè)務邏輯,協調領域模型與外部資源的交互。 - 基礎設施層:通過
OrderRepository實現數據存儲操作(在本示例中模擬數據庫)。 - Web層:通過
OrderController暴露RESTful API端點,供外部系統調用。
這種分層結構不僅使代碼更加模塊化、易于擴展,而且也使得系統的業(yè)務邏輯更加清晰,業(yè)務需求的變化可以靈活地反映到領域模型中,從而提高系統的可維護性和可擴展性。

浙公網安備 33010602011771號