Domanda

Stavo cercando di trovare un esempio chiaro e semplice di cosa significhi realmente un dominio anemico.C'è molta teoria in giro e anche molte domande con risposte precise.Tuttavia, non sono riuscito a ottenere un quadro chiaro fino a che punto si estenda realmente il significato di "dominio anemico".Pertanto, credo che sarebbe più semplice vedere un esempio pratico fittizio di progettazione di un dominio anemico e piuttosto chiederti come potrebbe essere trasformato in uno basato su un dominio...

Quindi, diciamo che abbiamo un'entità dati di tipo 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; }

}

E c'è la necessità di un immobile aggiuntivo chiamato "ActualState", che è uno stato calcolato:se l'Attività ha sotto-attività interne, il valore dipende strettamente dai figli, altrimenti il ​​"ActualState" è uguale a "Stato esplicito"

Se scrivo questa logica in un separato servizio classe (io li chiamo "motori") abbiamo:

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

IL prima domanda È:

Il codice sopra riflette una progettazione di dominio anemico, anche se il file TaskStateCalculator il servizio/motore fa parte del mio livello di dominio?Se sì, per evitarlo bisognerà spostare la logica all'interno del TaskData class (e rinominare TaskData A Compito).Ho ragione?

IL seconda domanda è (in realtà una catena di essi):

E se ci trovassimo in una situazione più difficile?Diciamo che c'è la necessità di una proprietà chiamata Calcola qualcosa dentro Compito entità e la logica di questa proprietà deve accedere all'intero Task deposito.In questo caso, il Compito la classe avrebbe una dipendenza da Deposito attività.Sarebbe ok?In che modo EF costruirebbe un'istanza di tale classe?Qual è l'alternativa?

È stato utile?

Soluzione

Stavo cercando di trovare un esempio chiaro e semplice di cosa significhi realmente un dominio anemico

È infatti davvero facile passare da un modello di dominio anemico a uno ricco.

  1. Imposta tutti i setter di proprietà su private e quindi aggiungi metodi se desideri modificare lo stato di un modello.
  2. Valuta tutto Legge di Demetra violazioni e aggiungere metodi ove opportuno.

Alla fine avrai un modello corretto.

Nel tuo caso incapsulerei quella logica all'interno TaskData poiché il tuo TaskStateCalculator viola la Legge di Demetra

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

un'altra cosa è che probabilmente non esporrei affatto la raccolta InnerTasks al mondo esterno (basta averla come campo membro).Ma è difficile dirlo perché non so come venga utilizzata la classe in altri scenari.

Perché setter privati

Ogni volta che è necessario modificare più di una proprietà, spesso è meglio descrivere il comportamento con un metodo, poiché in questo modo è impossibile dimenticare di modificare tutte le proprietà richieste.Un metodo descrive anche meglio ciò che stai tentando di fare rispetto alla modifica di un insieme di proprietà.

Anche se modifichi solo una singola proprietà, quella proprietà può impostare la classe in uno stato non valido poiché la modifica potrebbe non essere compatibile con il resto delle informazioni nella classe.Non dimenticare che l'incapsulamento è uno dei principi fondamentali dell'OOP

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top