[pugMI] Dubbi su architettura / data mapper / repository ecc... HELP! :)

Simone Magnaschi simone.magnaschi a gmail.com
Gio 16 Lug 2015 22:10:38 PDT


Ciao Giorgio,
grazie della risposta. Forse mi sono spiegato male. La mia intenzione non è
avere un grafo gigante per l'artista in questione.
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).
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?

Dato che anche le canzoni le foto le news i testi ecc potrebbero e anzi
sono degli aggregati per conto loro.


Il giorno 16 luglio 2015 19:06, Giorgio Sironi <info a giorgiosironi.com> ha
scritto:

> 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.
>
> 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.
> On 16 Jul 2015 11:05 am, "Simone Magnaschi" <simone.magnaschi a gmail.com>
> wrote:
>
>> Ciao a tutti,
>> volevo chiedervi un consiglio su come impostare una determinata sezione
>> di un progetto su cui stiamo lavorando.
>> Perdonatemi la lunghezza ma cerco di spiegarmi al meglio per inquadrarvi
>> bene la situazione.
>> Il cuore del problema è il Data Mapper Pattern e come gestire al meglio
>> le classi che entrano in gioco.
>>
>> 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.
>>
>> 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).
>> 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).
>>
>> 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.
>> 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.
>>
>> I problemi che sto avendo sono di natura architetturale e ora cerco di
>> entrare nel merito.
>>
>> Il progetto su cui stiamo lavorando è legato alla gestione di artisti
>> musicali e dati correlati.
>>
>> Nel nostro caso abbiamo diversi livelli di dati differenti sparsi su N
>> tabelle che rappresentano l'artista.
>>
>> PUNTO 1: DATI CHE DEFINISCONO L'ARTISTA
>>
>> a. dati di base (id, nome, tipo)
>> b. dati estesi (nazionalità, data di nascita / morte, biografia,
>> discografia ecc)
>> c. aliases (nomi alternativi, nomignoli ecc)
>> d. relazioni con altri entità di tipo artista (membri della band/ band
>> con cui l'artista ha suonato ecc)
>> e. relazioni con altre entità (genitori, fratelli ecc)
>> f. meta dati vari (profilo deezer, sito ufficiale, fb, tw, g+ ecc)
>> g. indice di copertura (identifica quanto l'artista è coperto dai nostri
>> contenuti)
>>
>>
>> PUNTO 2: ENTITA' ESTERNE CHE IN LINEA TEORICA SONO RELAZIONABILI
>> ALL'ARTISTA
>>
>> - articoli / news che lo riguardano
>> - recensioni
>> - videoclip
>> - foto
>> - citazioni
>> - ...
>>
>>
>> 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.
>>
>> 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:
>> - Alias punto c
>> - Meta punto f
>> - Relazioni punto d/e
>> - Copertura e ranking punto g (..ehm..)
>>
>> Il tutto mi va bene, ho il typehinting, la logica sta nelle classi e ok.
>>
>> L'ArtistRepository è un oggetto piuttosto grande che manda avanti e
>> indietro questi dati (complessivamente) tra tutte le tabelle coinvolte.
>> Ha classici metodi pubblici da repository:
>> - findById
>> - persist (gestisce sia insert che update)
>> - remove
>> - ...
>>
>> Questo è ok ma ora mi si presentano diversi problemi che non so bene come
>> risolvere. Questi i primi che mi vengono in mente:
>>
>> 1) PROBLEMI DI PERFORMANCE
>>
>> 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.
>>
>> 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.
>> 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.
>> 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.
>> 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.
>>
>> Questo mi genera una serie di perplessità:
>> - dal punto di vista dell'entità il concetto di cosa è stato idratato o
>> meno non ha assolutamente senso
>> - l'aggiunta di metodi come withBaseData o withRelations rende il
>> repository troppo specifico e difficilmente astraibile in un'interfaccia
>> repository generica.
>> - questo mi blocca nel caso volessi usare un decorator per aggiungere un
>> livello di logging piuttosto che di caching tramite file / redis ecc
>> - potrei certo costruire un'interfaccia ad hoc ma sto cercando di capire
>> se può essere ripensato il tutto per salvare capra e cavoli
>>
>> 2) PROBLEMI DI RECUPERO DATI ESTERNI
>>
>> 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.
>> Gli articoli o le foto ad esempio dovrebbero essere entità a sè con il
>> loro repository ecc. Come faccio a legare i due?
>>
>> Perdonatemi la lunghezza, e grazie in anticipo :)
>>
>> Simone
>>
>>
>> _______________________________________________
>> Milano mailing list
>> Milano a ml.grusp.org
>> http://ml.grusp.org/listinfo.cgi/milano-grusp.org
>>
>>
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://ml.grusp.org/pipermail/milano-grusp.org/attachments/20150717/97ed10a7/attachment.htm>


Maggiori informazioni sulla lista Milano