<div dir="ltr">Ciao Giorgio, <div>grazie della risposta. Forse mi sono spiegato male. La mia intenzione non è avere un grafo gigante per l'artista in questione.</div><div>Anzi ora il grafo come da mia mail originale va dai punti a fino al g. Quando parlo ad esempio di relazioni con altre artisti / persone,  nell'artista recuperato non sto memorizzando  i completi oggetti artista che sono relazionati con lui ma solo le informazioni di base che mi permettereanno di recuperarlo se serve (in questo caso l'id come dici tu). </div><div>Le mie perplessità derivano da come fare in modo di avere metodi che all'occorrenza possono recuperare solo parte di questi oggetti per ragioni di performance e come strutturare le entità collegate (le famose canzoni dell'artista): cosa è meglio fare? avere delle classi per le canzoni / foto / news  ecc e in esse avere i metodi di fetchByArtistId ad esempio?</div><div><br></div><div>Dato che anche le canzoni le foto le news i testi ecc potrebbero e anzi sono degli aggregati per conto loro.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">Il giorno 16 luglio 2015 19:06, Giorgio Sironi <span dir="ltr"><<a href="mailto:info@giorgiosironi.com" target="_blank">info@giorgiosironi.com</a>></span> ha scritto:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir="ltr">Purtroppo, un'altro progetto vittima del relazionale e della normalizzazione. Ti parlerei di CQRS e Aggregati, ma con due database diversi coinvolti mi sembra che il livello di legacy sia troppo elevato per farlo in modo responsabile.</p>
<p dir="ltr">Dico solo una cosa: non sei *obbligato* a costruire un grafo gigante di oggetti dove puoi navigare dall'Artista alle Canzoni e da lì ad un altro Artista di cui vedere le Foto. É lecito e sano fermarsi ad avere in un oggetto l'id di un altro.</p>
<div class="gmail_quote"><div><div class="h5">On 16 Jul 2015 11:05 am, "Simone Magnaschi" <<a href="mailto:simone.magnaschi@gmail.com" target="_blank">simone.magnaschi@gmail.com</a>> wrote:<br type="attribution"></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><div>Ciao a tutti,</div><div>volevo chiedervi un consiglio su come impostare una determinata sezione di un progetto su cui stiamo lavorando.</div><div>Perdonatemi la lunghezza ma cerco di spiegarmi al meglio per inquadrarvi bene la situazione.</div><div>Il cuore del problema è il Data Mapper Pattern e come gestire al meglio le classi che entrano in gioco.</div><div><br></div><div>Premetto che non ho esperienze di DDD o particolari esperienze con ORM e similari quindi alcune cose che dirò potrebbero sembrarvi stupide o completamente senza senso.</div><div><br></div><div>Nell'ottica di ristrutturare le classi che gestiscono gli "oggetti" su cui operiamo, ho iniziato a sviluppare un insieme di classi che si avvicinassero più o meno al data mapper pattern. Quindi ho le mie entità che sono POPOs con i loro metodi necessari per la logica delle entità stesse. Queste classi non hanno nessuna conoscenza del database (anche se hanno tra le proprietà gli id che a ben vedere con le entità c'entrano poco o niente).</div><div>Ho poi costruito le mie classi repository che vanno a fare avanti e indietro tra db e entità (idratano gli oggetti e allo stesso tempo fanno la persistenza mappando le proprietà cn i campi del db).</div><div><br></div><div>Non ho usato ORM come Doctrine (che tra l'altro non ho mai usato) o similari perchè l'applicazione che stiamo usando purtroppo è una legacy application in cui i dati sono sparsi tra due DB differenti (sql server + mysql). Ho preferito iniziare a costruire una semplice soluzione in casa piuttosto che sbattere la testa con una libreria che non sono sicuro che possa coprire il nostro caso.</div><div>L'approccio che ho usato, in sè, ci ha portato dei vantaggi, soprattutto per quanto riguarda il salvataggio e la persistenza dei dati che ovviamente ora sono in un unica classe ecc ecc.</div><div><br></div><div>I problemi che sto avendo sono di natura architetturale e ora cerco di entrare nel merito.</div><div><br></div><div>Il progetto su cui stiamo lavorando è legato alla gestione di artisti musicali e dati correlati.</div><div><br></div><div>Nel nostro caso abbiamo diversi livelli di dati differenti sparsi su N tabelle che rappresentano l'artista. </div><div><br></div><div>PUNTO 1: DATI CHE DEFINISCONO L'ARTISTA</div><div><br></div><div><span style="white-space:pre-wrap">        </span>a. dati di base (id, nome, tipo)</div><div><span style="white-space:pre-wrap"> </span>b. dati estesi (nazionalità, data di nascita / morte, biografia, discografia ecc)</div><div><span style="white-space:pre-wrap">       </span>c. aliases (nomi alternativi, nomignoli ecc)</div><div><span style="white-space:pre-wrap">     </span>d. relazioni con altri entità di tipo artista (membri della band/ band con cui l'artista ha suonato ecc)</div><div><span style="white-space:pre-wrap">    </span>e. relazioni con altre entità (genitori, fratelli ecc)</div><div><span style="white-space:pre-wrap">  </span>f. meta dati vari (profilo deezer, sito ufficiale, fb, tw, g+ ecc)</div><div><span style="white-space:pre-wrap">       </span>g. indice di copertura (identifica quanto l'artista è coperto dai nostri contenuti)</div><div><br></div><div><br></div><div>PUNTO 2: ENTITA' ESTERNE CHE IN LINEA TEORICA SONO RELAZIONABILI ALL'ARTISTA</div><div><br></div><div><span style="white-space:pre-wrap">   </span>- articoli / news che lo riguardano</div><div><span style="white-space:pre-wrap">      </span>- recensioni</div><div><span style="white-space:pre-wrap">     </span>- videoclip</div><div><span style="white-space:pre-wrap">      </span>- foto</div><div><span style="white-space:pre-wrap">   </span>- citazioni</div><div><span style="white-space:pre-wrap">      </span>- ...</div><div><br></div><div><br></div><div>Nel mio caso specifico l'entità artista può essere definita completamente con il punto 1. E' possibile costruire un artista istanziando un oggetto di tipo Artist. </div><div><br></div><div>L'oggetto è un grafo in cui ho delle proprietà di base che coprono i punti a/b e ho delle collezioni di altri oggetti (ognuno definitio a parte) che gestiscono:</div><div><span style="white-space:pre-wrap">       </span>- Alias punto c</div><div><span style="white-space:pre-wrap">  </span>- Meta punto f</div><div><span style="white-space:pre-wrap">   </span>- Relazioni punto d/e</div><div><span style="white-space:pre-wrap">    </span>- Copertura e ranking punto g (..ehm..)</div><div><br></div><div>Il tutto mi va bene, ho il typehinting, la logica sta nelle classi e ok.</div><div><br></div><div>L'ArtistRepository è un oggetto piuttosto grande che manda avanti e indietro questi dati (complessivamente) tra tutte le tabelle coinvolte. </div><div>Ha classici metodi pubblici da repository:</div><div><span style="white-space:pre-wrap">       </span>- findById</div><div><span style="white-space:pre-wrap">       </span>- persist (gestisce sia insert che update)</div><div><span style="white-space:pre-wrap">       </span>- remove</div><div><span style="white-space:pre-wrap"> </span>- ...</div><div><br></div><div>Questo è ok ma ora mi si presentano diversi problemi che non so bene come risolvere. Questi i primi che mi vengono in mente:</div><div><br></div><div>1) PROBLEMI DI PERFORMANCE</div><div><br></div><div>Se uso questo repository così com'è nell'applicazione ho dei problemi di performance (lasciando da parte il caching a cui arriverò dopo). Immaginiamo una scheda degli Oasis, se prendo gli oasis tramite repository e voglio rappresentare anche tutti i vari componenti, andrò a prendermi le relazioni, da qui creerò altri oggetti artista completi per poter semplicemente mostrare a video i loro nomi. Risultato, se per un artista mi ci vogliono 7-10 query nel DB, qui le moltiplico per tutti i componenti per nulla.</div><div><br></div><div>Allora ho pensato a questa cosa: il repository potrebbe avere dei metodi -con fluent interface eventualmente- del tipo withBaseData / withMeta ecc che dicono al repository quali parti dell'oggetto Artista andare a recuperare.</div><div>Quindi il mio $repo->fetchById() potrebbe diventare al caso $repo->withBaseData()->withRelations->fetchById() per andare a prendere un artista con i suoi dati di base ma anche le relazioni e nient' altro.</div><div>Il problema è che se poi lanciassi un persist mi cancellerebbe tutti i dati che non ho recuperato xè per il repository quell'artista non ha alias metadata o altro.</div><div>Quindi dovrei tenere traccia all'interno dell'entità artista di quali "parti" sono state idratate e quali no. In modo che all'atto del persist il repository può verificare cosa deve toccare e no.</div><div><br></div><div>Questo mi genera una serie di perplessità:</div><div><span style="white-space:pre-wrap">   </span>- dal punto di vista dell'entità il concetto di cosa è stato idratato o meno non ha assolutamente senso</div><div><span style="white-space:pre-wrap">    </span>- l'aggiunta di metodi come withBaseData o withRelations rende il repository troppo specifico e difficilmente astraibile in un'interfaccia repository generica. </div><div><span style="white-space:pre-wrap">                </span>- questo mi blocca nel caso volessi usare un decorator per aggiungere un livello di logging piuttosto che di caching tramite file / redis ecc</div><div><span style="white-space:pre-wrap">            </span>- potrei certo costruire un'interfaccia ad hoc ma sto cercando di capire se può essere ripensato il tutto per salvare capra e cavoli</div><div><br></div><div>2) PROBLEMI DI RECUPERO DATI ESTERNI</div><div><br></div><div>In questa situazione come è meglio recuperare i dati esterni? Come recupero ad esempio le foto o le news dell'artista? Devo renderli metodi dell'ArtistRepository e mapparli come relazioni nell'entità artista esattamente come faccio per gli altri dati? Così facendo non farei che peggiorare il punto sopra.</div><div>Gli articoli o le foto ad esempio dovrebbero essere entità a sè con il loro repository ecc. Come faccio a legare i due?</div><div><br></div><div>Perdonatemi la lunghezza, e grazie in anticipo :)</div><div><br></div><div>Simone</div><div><br></div></div>
<br></div></div><span class="">_______________________________________________<br>
Milano mailing list<br>
<a href="mailto:Milano@ml.grusp.org" target="_blank">Milano@ml.grusp.org</a><br>
<a href="http://ml.grusp.org/listinfo.cgi/milano-grusp.org" rel="noreferrer" target="_blank">http://ml.grusp.org/listinfo.cgi/milano-grusp.org</a><br>
<br></span></blockquote></div>
</blockquote></div><br></div>