MST

星途 面试题库

面试题:C# 领域驱动设计中聚合根的职责与实现要点

在C# 项目里运用领域驱动设计(DDD),请详细说明聚合根(Aggregate Root)的职责是什么,以及在代码实现时需要注意哪些要点,包括但不限于数据一致性、事务处理等方面。
17.1万 热度难度
编程语言C#

知识考点

AI 面试

面试题答案

一键面试

聚合根的职责

  1. 封装业务规则:聚合根负责封装与其相关的业务规则。例如,在一个电商系统中,订单作为聚合根,它包含了下单、支付、发货等一系列业务规则,确保这些操作符合业务逻辑。
  2. 管理聚合内实体:聚合根管理聚合内的其他实体。以订单为例,订单明细是订单聚合内的实体,订单聚合根负责维护订单明细的状态和关联关系,如添加、删除订单明细等操作。
  3. 确保数据一致性:在聚合范围内,聚合根确保数据的一致性。比如订单的总金额必须等于所有订单明细金额之和,聚合根在相关操作时要保证这种一致性。

代码实现要点

  1. 数据一致性
    • 属性验证:在聚合根的属性设置方法中进行验证。例如订单的下单时间必须晚于创建时间,在设置下单时间属性时添加验证逻辑。
    public class Order
    {
        private DateTime _creationTime;
        private DateTime _orderTime;
        public DateTime OrderTime
        {
            set
            {
                if (value <= _creationTime)
                {
                    throw new ArgumentException("下单时间必须晚于创建时间");
                }
                _orderTime = value;
            }
        }
    }
    
    • 操作后数据同步:当聚合根执行某些操作后,要确保聚合内相关数据同步更新。如订单支付成功后,要更新订单状态以及相关支付记录。
  2. 事务处理
    • 使用事务范围:在对聚合根进行复杂操作时,使用TransactionScope确保数据的原子性。例如,在订单发货操作中,可能涉及更新订单状态、库存扣减等多个操作,需要放在同一事务中。
    using (TransactionScope scope = new TransactionScope())
    {
        // 更新订单状态
        order.OrderStatus = OrderStatus.Shipped;
        // 库存扣减操作
        inventory.DecreaseStock(order.OrderDetails);
        scope.Complete();
    }
    
  3. 聚合根的唯一性标识
    • 设置唯一标识属性:每个聚合根都应有唯一标识,如订单的订单编号。这个标识在整个系统中用于唯一识别该聚合根。
    public class Order
    {
        public Guid OrderId { get; private set; }
        public Order()
        {
            OrderId = Guid.NewGuid();
        }
    }
    
  4. 聚合边界控制
    • 避免外部直接访问内部实体:聚合根作为聚合的入口,外部对象应通过聚合根来间接访问聚合内的实体。例如,外部代码不应直接访问订单明细,而是通过订单聚合根提供的方法来操作订单明细。
    public class Order
    {
        private List<OrderDetail> _orderDetails = new List<OrderDetail>();
        public void AddOrderDetail(OrderDetail detail)
        {
            _orderDetails.Add(detail);
        }
        public IEnumerable<OrderDetail> GetOrderDetails()
        {
            return _orderDetails;
        }
    }