【发布时间】:2014-07-24 22:49:49
【问题描述】:
我试图找到一个简单明了的例子来说明贫血域的真正含义。周围有很多理论,也有很多很好回答的问题。尽管如此,我仍然无法清楚地了解“贫血领域”的含义到底在多大程度上。因此,我相信看到一个虚弱的领域设计的虚拟实际示例会更简单,而不是问你如何将其演变为领域驱动的设计......
所以,假设我们有一个 TaskData 类型的数据实体:
public class TaskData
{
public Guid InternalId { get; set; }
public string Title { get; set; }
public string Details { get; set; }
public TaskState ExplicitState { get; set; }
public IEnumerable<TaskData> InnerTasks { get; set; }
}
并且需要一个名为“ActualState”的附加属性,这是一个计算状态:如果任务有内部子任务,则值严格取决于子任务,否则, “ActualState”等于“ExplicitState”
如果我在单独的 service 类(我称它们为“engines”)中编写此逻辑,我们有:
internal class TaskStateCalculator
{
public TaskState GetState(TaskData taskData)
{
if (taskData.InnerTasks.Any())
{
if (taskData.InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (taskData.InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
return taskData.ExplicitState;
}
}
第一个问题是:
即使 TaskStateCalculator 服务/引擎是我的域层的一部分,上述代码是否反映了贫乏的域设计? 如果是,为了避免这种情况,我们需要移动 TaskData 类中的逻辑(并将 TaskData 重命名为 Task)。我说的对吗?
第二个问题是(实际上是一连串):
如果我们遇到更困难的情况怎么办?假设在 Task 实体中需要一个名为 ComputeSomething 的属性,并且该属性的逻辑需要访问整个 Task 的 repository。在这种情况下,Task 类将依赖于TaskRepository。这样可以吗? EF 如何构造此类的实例?有什么选择?
【问题讨论】:
-
在考虑域模型时,我的第一条建议是忘记持久性,它会搅浑水。如果您有一段跨越实体的逻辑,答案可能是更高级别的聚合根或域级别的“服务”。
-
因此,仅与当前实例相关的逻辑需要放入实体中,但依赖于外部上下文的逻辑需要保留。是吗?
-
在这种情况下,看起来逻辑与该实体的子实体有关,因此也应由该实体管理。父母要对自己的孩子负责(不幸的是;-)
标签: c# entity-framework design-patterns anemic-domain-model