Question

J'essayais de trouver un exemple clair et simple de ce que signifie réellement un domaine anémique.Il y a beaucoup de théorie autour, et aussi beaucoup de questions bien répondues.Pourtant, je n'ai pas pu avoir une idée claire de l'étendue réelle de la signification du « domaine anémique ».Par conséquent, je pense qu'il serait plus simple de voir un exemple pratique factice de conception de domaine anémique et que de vous demander comment cela pourrait évoluer vers une conception pilotée par domaine...

Supposons donc que nous ayons une entité de données de type Données de tâche:

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

}

Et il y a le besoin d'une propriété supplémentaire appelée "État actuel", qui est un état calculé :si la Tâche a des sous-tâches internes, la valeur dépend strictement des enfants, sinon, le "État actuel" est égal à "État explicite"

Si j'écris cette logique dans un document séparé service classe (je les appelle "moteurs") nous avons:

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

Le première question est:

Le code ci-dessus reflète-t-il une conception de domaine anémique, même si le Calculateur d'état de tâche le service/moteur fait partie de ma couche de domaine ?Si oui, pour l'éviter, nous devrons déplacer la logique à l'intérieur du Données de tâche classe (et renommer Données de tâche à Tâche).Ai-je raison?

Le deuxième question est (en fait une chaîne d'entre eux) :

Et si nous étions confrontés à une situation plus difficile ?Disons qu'il existe un besoin pour une propriété appelée Calculerquelque chose à l'intérieur Tâche entité, et la logique de cette propriété doit accéder à l'intégralité de la tâche dépôt.Dans ce cas, le Tâche la classe aurait une dépendance sur Référentiel de tâches.Est-ce que ça irait ?Comment EF construirait-il une instance d’une telle classe ?Quelle est l’alternative ?

Était-ce utile?

La solution

J'essayais de trouver un exemple clair et simple de ce que signifie réellement un domaine anémique

Il est en fait très facile de passer d'un modèle de domaine anémique à un modèle riche.

  1. Définissez tous les setter de propriétés sur private puis ajoutez des méthodes si vous souhaitez modifier l'état d'un modèle.
  2. Évaluez tout Loi de Déméter violations et ajouter des méthodes le cas échéant.

Finalement, vous aurez un modèle correct.

Dans votre cas, j'encapsulerais cette logique à l'intérieur TaskData car votre TaskStateCalculator viole la loi de Déméter

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

une autre chose est que je n'exposerais probablement pas du tout la collection InnerTasks au monde extérieur (il suffit de l'avoir comme champ membre).Mais c'est difficile à dire car je ne sais pas comment la classe est utilisée dans d'autres scénarios.

Pourquoi des passeurs privés

Chaque fois que vous devez modifier plusieurs propriétés, il est souvent préférable de décrire le comportement avec une méthode, car il est alors impossible d'oublier de modifier toutes les propriétés requises.Une méthode décrit également mieux ce que vous essayez de faire que de modifier un ensemble de propriétés.

Même si vous modifiez simplement une seule propriété, cette propriété peut placer la classe dans un état non valide car la modification peut ne pas être compatible avec le reste des informations de la classe.N'oubliez pas que l'encapsulation est l'un des principes fondamentaux de la POO

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top