我试图找到一个清晰而简单的例子来说明贫血领域的真正含义。有很多理论,也有很多很好回答的问题。尽管如此,我还是无法清楚地了解“贫血领域”的含义到底有多大。因此,我相信看到贫血领域设计的虚拟实际示例,然后问您如何将其演变成领域驱动的设计,会更简单......

所以,假设我们有一个类型的数据实体 任务数据:

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; }

}

并且需要一个名为“的附加属性”实际状态”,这是一个计算状态:如果任务有内部子任务,则该值严格取决于子任务,否则,“实际状态“等于”显式状态"

如果我把这个逻辑写在一个单独的 服务 类(我称它们为“引擎“) 我们有:

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;
    }       
}

第一个问题 是:

上面的代码是否反映了贫乏的领域设计,即使 任务状态计算器 服务/引擎是我的域层的一部分?如果是,为了避免它,我们需要将逻辑移到 任务数据 类(并重命名 任务数据任务)。我对吗?

第二个问题 是(实际上是它们的链):

如果我们遇到更困难的情况怎么办?假设需要一个名为 计算一些东西 里面 任务 实体,这个属性的逻辑需要访问整个Task的 存储库. 。在这种情况下, 任务 类将依赖于 任务库. 。这样可以吗?EF 将如何构造此类的实例?还有什么选择呢?

有帮助吗?

解决方案

我试图找到一个清晰简单的例子来说明贫血领域的真正含义

事实上,从贫乏的领域模型转变为丰富的领域模型非常容易。

  1. 将所有属性设置器设置为 private 如果您想更改模型的状态,然后添加方法。
  2. 评估全部 德墨忒耳定律 违规并在适当的地方添加方法。

最终你将得到一个正确的模型。

在你的情况下,我会将该逻辑封装在里面 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 的核心原则之一

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top