Вопрос

Я пытался найти ясный и простой пример того, что на самом деле означает анемичный домен.Вокруг много теории, а также много вопросов с хорошими ответами.Тем не менее, я не смог получить четкого представления о том, в какой степени на самом деле имеет значение "анемичный домен".Поэтому я считаю, что было бы проще увидеть фиктивный практический пример дизайна анемичного домена, чем спрашивать вас, как это можно развить до дизайна, управляемого доменом...

Итак, предположим, у нас есть объект данных типа Данные задачи:

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

Тот Самый первый вопрос является:

Отражает ли приведенный выше код анемичный дизайн домена, даже если Вычислитель состояния задачи сервис / движок является частью моего Доменного уровня?Если да, то, чтобы избежать этого, нам нужно переместить логику внутрь Данные задачи класс (и переименовать Данные задачи Для Задача).Я прав?

Тот Самый второй вопрос является (на самом деле цепочкой из них):

Что, если у нас возникнет более сложная ситуация?Допустим, существует потребность в свойстве, называемом Вычислительное нечто внутри Задача сущность, и логика этого свойства должна обеспечивать доступ ко всей задаче целиком. хранилище.В этом случае Задача класс будет зависеть от Хранилище задач.Было бы это нормально?Как бы 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 внешнему миру (просто разместил бы ее как поле-член).Но трудно сказать, так как я не знаю, как этот класс используется в других сценариях.

Почему частные сеттеры

Каждый раз, когда вам приходится изменять более одного свойства, часто лучше описать поведение с помощью метода, так как тогда невозможно забыть изменить все необходимые свойства.Метод также лучше описывает то, что вы пытаетесь сделать, чем изменение набора свойств.

Даже если вы просто измените одно свойство, это свойство может перевести класс в недопустимое состояние, поскольку изменение может быть несовместимо с остальной информацией в классе.Не забывайте, что инкапсуляция - один из основных принципов ООП

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top