如何通过聚合根控制不变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过聚合根控制不变量相关的知识,希望对你有一定的参考价值。

如果我有两个类[Shift,ShiftDetails],其中[Shift]是聚合根。基于特定字段,我想约束ShiftDetails的实例数。


我创建了一个ShiftDetailsView类,然后在Shift聚合根中创建两个方法来控制不变量:

  • public IEnumerable ConstructShift(); //基于NumberOfSuccessions字段

此方法应基于该字段创建多个已初始化的qazxsw poi,然后将它们添加到列表中,并将结果作为IEnumerable返回给用户(开发人员)。

然后用户应该在填充从前一个方法返回的初始IEnumerable后调用ShiftDetailsView

  • public List CompleteShift(IEnumerable shiftDetailsViews)

我做了两个单独的步骤来控制通过聚合根的子数量,我认为有更好的方法来保证整个事物的(ACID)。


根据评论,这个问题需要更多的澄清,因为我试图简化问题,我犯了一个错误并改变了真正的问题。因为当我们处理域问题时,我们必须准确并澄清确切的问题。所以我会尝试更详细地解释它。

我有以下两个聚合:

1. First Aggregate

1-WorkingSystem :(聚合根)

CompleteShift

例:

    private readonly ICollection<WorkingTime> _assignedWorkingTimes;

    public string Name { get; private set; }
    public short NumberOfSuccessions { get; private set; }
    public Week WeekStart { get; private set; }
    public bool IsActive { get; private set; }
    public bool IsDefault { get; private set; }
    public short NumberOfWeekends { get; private set; }
    public virtual ICollection<WorkingTime> AssignedWorkingTimes { get => _assignedWorkingTimes; }

2 WorkingTime:

 Id |Name     | NumberOfSuccessions|WeekStart|IsActive|NumberOfWeekends 
  1 |Employees|       2            |Sunday   |  1     |   2
  2 |Lecturers|       1            |Saturday |  1     |   1

例:

public string Name { get; set; }
public short NumberOfHours { get; set; }
public int WorkingSystemId { get; private set; }

2.第二集合

3-Shift(聚合根)。

Id|Name   |  NumberOfWorkingHours  | WorkingSystemId 
 1|Summer |  8                     | 1
 2|Winter |  6                     | 1
 3|General|  8                     | 2

例:

private readonly List<ShiftDetail> _assignedShiftDetails;
public string Name { get; set; }
public ShiftType ShiftType { get; set; }
public int WorkingSystemId { get; set; }
public virtual WorkingSystem WorkingSystem { get; set; }
public virtual IEnumerable<ShiftDetail> AssignedShiftDetails { get => _assignedShiftDetails; }

4- ShiftDetails:

Id|Name            |ShiftType | WorkingSystemId 
1 |restaurant-shift|Morning   |  1

例:

public Guid ShiftId { get; private set; }
public int WorkingTimeId { get; set; }
public DateTimeRange ShiftTimeRange { get; set; }
public virtual WorkingTime WorkingTime { get; set; }

现在我想根据每个WorkingSystem的 ShiftId = 1|WorkingTimeId = 1|ShiftStart = 8:00|ShiftEnd = 16:00 ShiftId = 1|WorkingTimeId = 2|ShiftStart = 9:00|ShiftEnd = 15:00 约束细节数量!因为我可以在我的聚合根NumberOfSuccessions访问WorkingSystemId然后我可以访问此信息。

你能帮我根据聚合根中的字段控制实例数吗?

答案

你能帮我根据聚合根中的字段控制实例数吗?

这两种方法的使用仅限于创造新的转变。因为我是DDD的新手,我想我并没有以正确的方式约束不变量

哦,我明白了 - 你特别担心在创建聚合的事务中会发生什么。

Eric Evans(第6章)描述的通常模式是域模型将公开一个知道如何从应用程序获取数据并返回新聚合实例的工厂。

在该工厂中,您将创建构成聚合的初始状态的所有值。这些值理解他们自己的约束(“我是一个Shift,所以我需要一个大于或等于零的整数”;“我是一个Amount,所以我需要一个非null的Money和一个非null的Amount)。

工厂接受来自应用程序的数据,构造值的图形,最后调用具有当前状态的聚合的构造函数。

在模型中拥有负责验证已传入数据的值,并且可以包括验证另外两个值是否一致的值,这是完全正常的事情。

因此,例如,你的工厂可能会采用CurrencyCodeNumberOfDetails,并从中产生List<ShiftDetails>类型,最终将从中构建聚合体。

关于这种方法的一个非常好的读物是VerifiedDetailsScott Wlaschin's

另一答案

我将一个名为AssignedShiftDetail(ShiftDetail shiftDetail)的方法添加到Shift类中,并将在此方法中实现任何相关的逻辑。

以上是关于如何通过聚合根控制不变量的主要内容,如果未能解决你的问题,请参考以下文章

如何运用领域驱动设计 - 聚合

聚合根和实体框架

应用领域驱动设计规则“仅通过聚合根访问聚合”时如何画线

DDD领域驱动设计实战-聚合(Aggregate)和聚合根(AggregateRoot)

数据库和聚合根的存储库模式

域驱动设计:如何访问聚合根的子节点