DDD: operazioni di servizio / pronti contro termine su ID o istanze?

1

Potrebbe essere sciocco, ma: supponiamo di voler eliminare un Book dal repository. Dovrei:

  • deleteBook(bookId) - invia l'ID poiché nella maggior parte del tempo, l'ID viene passato dall'interfaccia utente

o

  • deleteBook(Book) - ma poi devo prima recuperare il libro? E questa sarebbe solo una scorciatoia per sopra: deleteBook(book.getId()) .

Il mio coraggio mi dice che entrambi dovrebbero esistere. Qualche saggezza su questo?

    
posta lawpert 30.10.2014 - 10:48
fonte

2 risposte

1

I repository sono cittadini di prima classe nel modello di dominio, quindi dovrebbero operare in termini di linguaggio ubiquo utilizzando entità e oggetti valore. Pertanto, è necessario evitare di denominare i metodi del repository dopo le operazioni CRUD e utilizzando gli ID delle tabelle del database (chiavi primarie) per gestire le entità. Invece dovresti concentrarti sul tuo vocabolario aziendale e cercare di derivare concetti importanti. Molte volte le radici aggregate hanno un'identità chiara nel dominio del problema ed è prassi comune nel mondo DDD modellare tale identità come oggetto valore.

Tornando ai libri. Non sei sicuro del tuo modello di dominio ma forse potresti utilizzare ISBN o simili come ID per i tuoi libri. O potresti voler utilizzare una combinazione di ISBN e altri identificatori generati dal tuo sistema. Ad ogni modo, penso che questo concetto di identità di un libro meriti di essere una parte del tuo modello come oggetto di valore.

A seconda delle tue esigenze questo è ciò che potrebbe essere il tuo repository

public interface BookRepository {
    public Book find(ISBN isbn);
    public Book find(BookID id);

    public void store(Book book);

    public void remove(ISBN isbn);
    public void remove(BookID id);
    public void remove(Book book);
}
    
risposta data 30.10.2014 - 12:15
fonte
0

Ho sempre trovato utile per il repository tracciare le entità che idrata insieme ai loro valori chiave primari in modo tale che rimanga nel contesto dell'applicazione. Ad esempio, nella tua situazione, potrei avere qualcosa del genere sul mio BookRepository.

public class SqlBookRepository : IBookRepository
{
    public static List<KeyValuePair<string, object>> BookReferences = new List<KeyValuePair<string, object>>();

    public Book this[ISBN isbn]
    {
        get
        {
            if (!BookReferences.Any(b => b.Value.ISBN == isbn))
            {
                DBBook bookWithISBN = //TODO:  Call db and get the book.       
                Book book = HydrateBook(bookWithISBN);
                BookReferences.Add(new KeyValuePair(DBBook.ID, book));
                return book;
            }
            else
                return BookReferences.Single(b => b.ISBN == isbn);
        }
    }

    public bool Remove(Book book)
    {
        if (!BookReferences.Any(b => b.Value == book))
            return false;

        object bookId = BookReferences.Where(b => b.Value == book).Key;
        DataContext.Books.Remove(bookId);
    }
}
    
risposta data 30.10.2014 - 17:14
fonte

Leggi altre domande sui tag