DDD实现1

DDD实现1

写在开头

我们之前已经通过事件建模获得了总体的情况,接下来我们需要使用代码实现它,同时积极与领域专家进行交流反馈,不断修正我们的领域模型。

注意:我们不可能在一开始就获得优秀的领域模型,它是在不断的交流反馈中慢慢完善的!!!

实现

有界上下文(Bounded Context)

设备系统中包含多个模块,比如设备点检,设备维护,设备维修等等,他们每一个都是单独的有界上下文,我们所实现的正是设备维护上下文。

注意:有界上下文之间通过ACL(防腐层),Shared Kernel(共享内核)或者集成事件进行交流!

聚合(Aggregate)

设备维护上下文包含多个聚合,如设备维护项,维护计划,维护任务等。

在这里,我选择直接将四个绿色便签纸当作聚合。

维护记录实际上可以属于维护任务等聚合,我需要使用维护记录做报表,所以将其当做了一个单独的聚合

聚合根(Aggregate Root)

聚合根,如其名,如果想要访问聚合内部的其他实体,必须通过聚合根,比如在EF Core中,使用聚合根中的导航属性进行查询

public class MaintenanceItem:EntityBase<Guid>,IAggregateRoot
{
  public string? Name { get; private set; }
  public string? Content { get; private set; }
  public Guid EquipmentTypeId { get; private set; }
  public MaintenanceCycle? MaintenanceCycle { get; private set; } 
  
  public MaintenanceItem(string name, string content, Guid equipmentTypeId,  MaintenanceCycle maintenanceCycle)
  {
    Name = Guard.Against.NullOrWhiteSpace(name, nameof(name));
    Content = Guard.Against.NullOrWhiteSpace(content, nameof(content));
    EquipmentTypeId = Guard.Against.Default(equipmentTypeId, nameof(equipmentTypeId));
    MaintenanceCycle = Guard.Against.Null(maintenanceCycle, nameof(maintenanceCycle));
  }
//EF Core 使用
  private MaintenanceItem()
  {
    
  }
}

以上代码展示了一个聚合根,它继承了IAggregateRoot接口

代码中的Guard防御性编程的实现,提前验证参数的有效性,从而避免系统进入非法状态.

实体(Entity)

相信你已经发现了聚合根还继承了EntityBase<Guid>,这正是实体基类,设置了该实体的IdGuid类型。

实体是有唯一标识(Id)的,生命周期和身份明确。

值对象(Value Object)

值对象是没有唯一标识的,它由一组属性区分,同时值对象不可变,只能整个替换。

C#中,由于record可以通过with改变,所以建议自己封装class

上面代码中的MaintenanceCycle正是一个值对象

public class MaintenanceCycle(MaintenanceCycleType cycleType, int intervalTime):ValueObject
{
  public MaintenanceCycleType CycleType { get; private set; }=Guard.Against.Null(cycleType);
  public int IntervalTime { get; private set; } = Guard.Against.NegativeOrZero(intervalTime);
  public int DayOfPeriod { get; private set; } = 0;
  public void SetDayOfPeriod(int dayOfPeriod)
  {
    DayOfPeriod = Guard.Against.NegativeOrZero(dayOfPeriod);
  }

  protected override IEnumerable<object> GetEqualityComponents()
  {
    yield return CycleType;
    yield return IntervalTime;
    yield return DayOfPeriod;
  }
}

EF Core中使用OwnsOneOwnsMany配置

  public void Configure(EntityTypeBuilder<MaintenanceItem> builder)
  {
    builder.OwnsOne(builder=> builder.MaintenanceCycle, mc =>
    {
    });
  }

写在最后

本期已经覆盖了一些内容,关于其他内容,我将会在下一期补充。

posted @ 2025-05-23 21:06  ssz0312  阅读(26)  评论(0)    收藏  举报