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>,这正是实体基类,设置了该实体的Id是Guid类型。
实体是有唯一标识(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中使用OwnsOne或OwnsMany配置
public void Configure(EntityTypeBuilder<MaintenanceItem> builder)
{
builder.OwnsOne(builder=> builder.MaintenanceCycle, mc =>
{
});
}
写在最后
本期已经覆盖了一些内容,关于其他内容,我将会在下一期补充。

浙公网安备 33010602011771号