Immagina un'applicazione che ti permetta di aggiungere elementi pubblicitari a un preventivo. Il risultato finale è come un addetto alle vendite che ti fornisce un foglio stampato con informazioni quali il nome dell'azienda, il nome della persona di vendita e vari articoli di servizio stampati sul preventivo insieme a prezzi, descrizione e quantità.
Per implementarlo a livello di database, ho tabelle Item
(contiene 0-to-many items per Quote) e QuoteMeta
(contiene meta-informazioni sulle virgolette come chi ha creato la citazione, il numero di preventivo, la revisione, lo stato, ecc).
PoihounoggettodominiochiamatoQuote
,chenonèaconoscenzadirettamentedellivellodatabase,maricevedatisiadaItem
siadaQuoteMeta
.IlQuote
èil"foglio preventivo" precedentemente descritto.
La mia domanda è come gestire questo oggetto dominio quando ho più di una tabella che lo rappresenta internamente. Ad esempio, con il mio oggetto dominio Quote
posso fare qualcosa del tipo ...
Repository singolo, oggetto Dominio singolo
//Repository populates $quote from both database tables
$quote = (new QuoteRepository())->getQuoteById($id);
$quote->getQuoteNumber(); //gets data from quote metadata table
$quote->getItemByLineNumber(5); //gets an item from items table
Quanto sopra "sposa" le tabelle nell'oggetto Quote del dominio. QuoteRepository
gestisce le query indirizzate ae da entrambe le tabelle del database. La mia domanda è ... posso farlo?
Ad esempio, sarà meglio tenere separati i concetti, forse così?
Repository multipli, oggetti di domini multipli
//repository strictly deals with quote meta data
$quoteMeta = (new QuoteMetaRepository())->getQuoteMetaById($id);
$quote->getQuoteNumber();
//repository strictly deals with item handling
$items = (new ItemRepository())->getItemsByQuoteId($id);
$items->getItemByLineNumber(5);
Qui le preoccupazioni sono più separate, ma ho complessità nel trattare con più oggetti, quando la rappresentazione fisica di Quote è tipicamente intesa come gli elementi + i metadati di citazione uniti insieme. Non hai solo articoli senza metadati e non ha molto senso avere metadati senza elementi di servizio.
Detto questo, è preferibile tenere separati i repository, o insieme? E se separato, come gestisco cose come le JOIN di tabella che operano su entrambe le tabelle? A quale repository vanno?
Gestione di più tabelle
Per cambiare un po 'le marce, ho qualche scopo del codice di cui eliminare un oggetto. Un record oggetto viene eliminato dalla tabella. Quindi i riferimenti ad altri dati che sono legati all'elemento vengono cancellati da altre 5 tabelle (cose come grafici, design, ecc. E altri dati che appartengono all'elemento). Se questa "eliminazione oggetto" fosse un metodo a singolo gestore che cancelli i dati da più tabelle direttamente nel posto di un metodo, o ogni tabella abbia il proprio rispettivo codice e classe del gestore di repository, e posso chiamare ciascun gestore per cancellare la loro porzione di l'articolo?
Inoltre, nell'esempio in cui elimino l'elemento, non mi interessa molto di QuoteMeta
tabella o entità. Quindi potrei usare solo il ItemRepository
handler da solo, il che mi spinge verso repository separati in questo caso.
Note su ORM
Nel mio codebase sto usando un ORM, dove ho entità, come Item
Entità corrisponde a item
tabella, e QuotaMeta
corrisponde a quote_meta
. Il focus della mia domanda però non è su un ORM. ORM fornisce un modo conveniente per popolare le mie entità dalle tabelle, ma senza ORM potrei comunque compilare Entità (cioè tramite mysqli_fetch_object
), altrimenti utilizzerei gli array. La domanda continua: come modellare i miei oggetti di dominio e i repository corrispondenti? Ho ... ne ho uno per tabella o vado a un livello più alto di astrazione, dove lavoro su più tabelle per singolo dominio / repository?
Considerazioni finali ..
Per essere super-specifico, ho un oggetto dominio Quote
che opera su entrambe le tabelle, oppure ho separato ItemGroup
e QuoteMeta
oggetti, dove uno gestisce gli articoli che appartengono al Preventivo ma non fa t cura dei metadati e uno gestisce i metadati di Quote, senza occuparsi degli elementi che appartengono ad esso?