DDD: Come fare riferimento / selezionare un oggetto valore all'interno dell'aggregato?

3

Abbiamo un insieme di:

  • entità: Poll (che rappresenta una domanda)
  • due o più oggetti valore Choice

L'aggiunta di scelte avviene tramite Poll , il repository memorizza solo l'aggregato, cioè tutto viene eseguito come previsto.

Ora, ho bisogno di selezionare il Choice specifico scelto dall'utente. Dall'interfaccia utente avrò solo il choiceId della scelta selezionata. Quindi il mio metodo Poll.voteForChoice() sarà:

  • voteForChoice(choiceId) - dove passo l'id di scelta alla radice aggregata, quindi itera le sue scelte e trova la scelta target in modo da incrementare il conteggio. Tuttavia, stiamo usando l'ID qui per la scelta, e la scelta è l'oggetto valore.
  • voteForChoice(Choice) - dove stiamo inviando l'oggetto valore completo, ovvero ho bisogno di crearlo prima di votare. Ciò significa anche che avrò bisogno di avere un Repo per le scelte, e sono oggetti di valore, così che si scontri con tutto ciò che ho imparato;)
  • o dovrebbe essere: Poll.getChoice(choiceId).vote() .
  • oppure Choice è in realtà un'entità, quindi dovremmo utilizzare Repository per recuperare la scelta: ChoiceRepo.find(id).vote() .

Caso semplice, ma qual è la risposta corretta nel mondo DDD?

    
posta lawpert 29.10.2014 - 00:32
fonte

2 risposte

3

A seconda del grado di collaborazione della tua applicazione, potresti trovarti nei guai se 2 o più utenti cercano di incrementare contemporaneamente lo stesso Choice . Questo accadrà se si tratta di un VO o di un'entità nello stesso aggregato di Poll .

Per me il confine di consistenza naturale implicito nell'azione di dominio del voto include l'utente. Quindi suggerirei una vera radice di aggregazione PollChoice con un collegamento all'Utente, o se ci sono più scelte per sondaggio, un PollResponse AR contenente tutte le scelte (che possono essere VO) fatte da un particolare utente ad un sondaggio specifico.

Modifica : qualcosa in questo senso

class PollResponse {

  int pollId;
  int userId;
  Choice choice;
  Datetime dateResponded;
}
    
risposta data 29.10.2014 - 14:58
fonte
2

Credo che un oggetto valore dovrebbe essere riferito al suo valore perché è questo che lo rende unico, né un GUID né un ID locale.

Considera un esempio del mondo reale

1) What web browser do you use at work?

  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

2) What web browser do you use at home?

  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

Come voteresti nel mondo reale? Probabilmente diresti qualcosa del tipo "Per il primo sondaggio, voto per 'Firefox'" o "Per il secondo sondaggio, scelgo 'A'". Quindi, ci sono alcuni modi per modellare il comportamento di voto

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);

poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

D'altra parte, non c'è niente di sbagliato nel creare un'istanza di un oggetto valore al di fuori dell'ambito del suo aggregato senza usare un repository

poll1.voteForChoice(new Choice("Firefox"));
poll2.voteForChoice(new Choice("Chrome"));

Quindi, sembra che tu possa utilizzare la seconda opzione per il metodo voteForChoice . Il primo usa ID che suggerisce che Choice s sia modellato come entità. Il terzo si sente sbagliato come un'astrazione che perde e una violazione dell'incapsulamento. Quella precedente è sbagliata a causa dell'utilizzo di un repository per un oggetto valore.

Aggiorna

Punto importante. Non esiste una singola ricetta su come modellare il tuo dominio anche se è un caso comune nel mondo reale. Puoi progettare Choice s come oggetti valore e avere una proprietà Map<Choice, Counter> choices nel tuo Poll s. Oppure puoi progettarlo come entità e avere il contatore come parte di un Choice . Inoltre, potresti voler avere una raccolta List<User> users nell'entità Choice per tenere traccia degli utenti che hanno votato per un particolare Choice .

So di aver reso ancora più confuso per te, ma la cosa che voglio sottolineare è che devi decidere da solo di quale tipo di modello di dominio hai bisogno. La mia risposta si basava sull'ipotesi derivata dalla tua domanda secondo cui gli oggetti valore sono ciò di cui hai bisogno.

UPDATE 2

Si scopre che, secondo Eric Evans, quando si è tentati di creare una sorta di identificatore per un oggetto valore anche se è locale, si dovrebbe considerare di farlo diventare un'entità.

    
risposta data 29.10.2014 - 09:52
fonte

Leggi altre domande sui tag