我试图找到一个清晰而简单的例子,说明贫血领域的真正含义。有很多理论,还有很多很好的答案。尽管如此,我无法清楚地了解到什么程度的贫血领域"意思真的如此。因此,我相信看到一个贫血领域设计的虚拟实际例子会更简单,而不是问你怎么可能演变成一个域驱动的...
所以,我们假设我们有一个 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; }
}
还需要一个名为&#34; ActualState &#34;的附加属性,这是一个计算状态:如果任务有内部子任务,则该值严格依赖于孩子,否则,&#34; ActualState &#34;等于&#34; ExplicitState &#34;
如果我在一个单独的服务类中编写此逻辑(我称之为&#34; 引擎&#34;),我们有:
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 )。我是对的吗?
第二个问题是(实际上是他们的链):
如果我们遇到更困难的情况怎么办?让我们说在任务实体中需要一个名为 ComputeSomething 的属性,并且该属性的逻辑需要访问整个任务< EM>存储库。在这种情况下,任务类将依赖于 TaskRepository 。这样可以吗? EF将如何构建此类的实例?有什么替代方案?
答案 0 :(得分:6)
事实上,从贫血领域模式到富裕领域模型实际上很容易。我试图找到一个清晰而简单的例子,说明贫血领域的真正含义
private
,然后在要更改模型状态时添加方法。 最终你会有一个正确的模型。
在你的情况下,我会将这个逻辑封装在TaskData
中,因为你的TaskStateCalculator违反了得墨忒耳法
public class TaskData
{
public Guid InternalId { get; private set; }
public string Title { get; private set; }
public string Details { get; private set; }
public TaskState ExplicitState { get; private set; }
public IEnumerable<TaskData> InnerTasks { get; private set; }
public TaskState GetState()
{
if (!InnerTasks.Any())
return ExplicitState;
if (InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
}
另一件事是我可能根本不会将InnerTasks集合暴露给外界(只是将它作为成员字段)。但我很难说,因为我不知道在其他场景中如何使用该类。
为何选择私人制定者
每次你必须改变多个属性时,用方法描述行为往往更好,因为它不可能忘记改变所有必需的属性。与更改一组属性相比,方法还更好地描述了您要做的事情。
即使您只更改了一个属性,该属性也可以将类设置为无效状态,因为更改可能与类中的其余信息不兼容。别忘了封装是OOP的核心原则之一