Devo recuperare entità correlate dall'entità padre o dal livello di servizio?

5

Diciamo che ho una struttura di applicazione a tre livelli, con livelli di presentazione, servizio e dati. Il livello dati è gestito da un ORM e ha due modelli / entità, Show e Episode , con una relazione uno-a-molti (uno spettacolo è costituito da molti episodi).

Nel livello di servizio c'è un ShowService , che può gestire gli spettacoli. L'applicazione dovrà spesso visualizzare solo gli episodi in cui il tempo di pubblicazione è nel passato (cioè che sono pubblicati).

Ora alla domanda - dove dovrei inserire la logica per recuperare gli episodi?

Penso che abbia senso avere un metodo getPublishedEpisodes() nel modello Show / entity, perché gli episodi sono in sostanza le parti che compongono uno spettacolo. L'ORM che sto usando (RedBeanPHP) renderebbe molto facile implementare qualcosa di simile nel modello Show :

public function getPublishedEpisodes(){
    $allEpisodes = $this->ownEpisodeList;
    return filterPublished($allEpisodes);
}

Ora posso solo chiamare

$episodes = $show->getPublishedEpisodes();

e tutto ciò di cui ho bisogno è un Show per poter ottenere gli episodi pubblicati.

L'altra opzione sarebbe mettere il metodo in ShowService , che in qualche modo non sembra naturale, ma ho la sensazione che questo sia il modo "corretto" per farlo. Sto pensando che dovrei fare qualcosa di simile in ShowService :

public function getPublishedEpisodes(Show $show){
    $allEpisodes = $show->ownEpisodeList;
    return filterPublished($allEpisodes);
}

Ma poi avrei sempre bisogno di ottenere ShowService ogni volta che voglio ricevere episodi pubblicati. Con l'altro approccio posso passare intorno a Show oggetti dappertutto e basta chiamare $show->getPublishedEpisodes() ogni volta che voglio.

La prima opzione, che è molto più semplice, almeno a breve termine, mi dà problemi che non riesco a vedere in questo momento?

    
posta Magnus W 02.02.2017 - 17:57
fonte

1 risposta

0

Questa è una domanda difficile a cui molti hanno messo in evidenza tramite i commenti, ma suppongo che lo appesiderò.

Il mio primo pensiero è quello di fare ciò che è meglio per la tua applicazione. Possiamo approfondire la teoria di DDD e simili in cui potrei avere un'opinione diversa (e lo farò, se tu porti con me).

Se per te è più sensato caricare semplicemente un show tramite il tuo ORM e chiamare un metodo come getPublishedEpisodes() di farlo! Se ti iscrivi ad un approccio agile o ti rifatti spesso, puoi sempre modificarlo in seguito. È possibile (e probabile) che il tuo primo tentativo di un modello o di un'architettura sia sbagliato ... A volte non sappiamo di cosa abbiamo bisogno fino a quando non ci proviamo.

Se ORM è piuttosto non invadente e non impone una dipendenza diretta dalla classe Show , allora probabilmente stai andando bene per quella via. Aspect Oriented Programming è qualcosa che potresti voler esaminare e che funziona bene con le tue idee. Tuttavia, potrebbe non essere possibile in PHP o con il tuo ORM.

Ad ogni modo, troverei più pulito usare i tuoi modelli per incapsulare la logica aziendale, e in tal senso immagino che il tuo Episodes sia figlio di Show . Se è così, probabilmente avrei un ShowRepository per caricare Show dove il repository è una dipendenza di ShowService . Il ShowService gestirà il collegamento delle entità e gestirà il coordinamento della logica aziendale.

Nella mia versione di questa app, solo da una vista di 1000 piedi, quando ho caricato Show avrei praticamente caricato tutto il Episodes con esso. Quando avevo bisogno di ottenere solo il Episodes per una vista particolare, potrei usare qualche forma di Oggetto di query per eseguire una query più personalizzata. L'unica ragione per cui lo farei, tuttavia, è se la mia app fosse davvero poco performante usando l'idea originale di recuperare il Show con Episodes allegato.

L'utilizzo dell'idea dell'oggetto Query porta a CQRS che è un argomento piuttosto avanzato e potrebbe non valerne la pena la tua applicazione.

Per ripetere, fai ciò che senti più semplice da capire e mantenere per te e la tua squadra. Possiamo solo dare tanti consigli su internet, soprattutto senza vedere e capire l'applicazione e il suo dominio.

Detto questo - e prenderei il resto con un pizzico di sale - se dovessi scrivere questa applicazione, preferirei un approccio diverso, probabilmente più vicino a quello della tua idea ShowService .

Quando dici "entità", penso a DDD. Questo potrebbe essere o non essere accurato. Molti provider ORM chiamano i loro modelli "entità" - ahem Entity Framework ahem - che è una specie di termine improprio. Entity Framework "entità" sono in realtà solo Oggetti di trasferimento dati . A mio parere, le "entità" sono entità in relazione a Domain Driven Design. Le entità, come si vede qui, sono definite dalla loro identità . Sono i modelli principali che rappresentano i concetti strategicamente importanti di un dominio o azienda.

Se sottoscriviamo modelli DDD e DDD, le nostre entità non avranno mai dipendenze come farebbe un servizio. Pensa a un ordine e alle sue linee di ordine corrispondenti. Le righe dell'ordine possono esistere in isolamento senza un ordine? Puoi avere una riga d'ordine di Rouge? No. Una parte importante dell'identità della riga d'ordine è l'ordine stesso. L'ordine è l'entità aggregata .

Quindi, in questo caso, Show sembra essere il tuo aggregato mentre Episodes sembra come entità figlio. Se questo è il caso, non avresti nemmeno un mezzo per caricare direttamente Episodes dal database. Verrebbero sempre con Show . Questo è il motivo per cui potresti pensare che ShowService sia il modo "corretto" per risolvere il tuo problema. Probabilmente hai sentito qualcosa lungo queste linee da qualche parte lungo la strada. Forse hai già familiarità con DDD e tutto quello che sto dicendo è inutile. Ad ogni modo, ho pensato che avrei condiviso.

DDD è fantastico e offre molta chiarezza su come dovresti pensare alla tua app e su dove si trova una particolare logica, ma DDD è difficile. Se la tua app è una semplice app CRUD con poca logica, eviterei del tutto il DDD. È solo un sacco di lavoro e molto difficile da fare bene.

Questa era una tangente, ma speriamo che aiuti.

    
risposta data 03.02.2017 - 05:11
fonte

Leggi altre domande sui tag