Esiste un modello di progettazione per gestire profonde relazioni molti-a-molti?


10

Ho difficoltà a definire questo modello di dati che ho riscontrato lavorando su diverse applicazioni.

Consiste in:

  1. Un tipo di oggetto composto da molti oggetti stessi
  2. Un secondo tipo di oggetto, in cui ogni istanza "ha molti" del primo oggetto
  3. E, ciascuno dei sotto-oggetti del primo oggetto è modificabile per ogni associazione al secondo tipo di oggetto.

Un semplice esempio potrebbe essere:

  1. Un corso di programmazione costituito da una serie di lezioni
  2. Le lezioni sono composte da un set di compiti.
  3. Un corso può essere assegnato a uno studente.
  4. Tuttavia, una volta assegnato un corso a uno studente, ogni lezione e / o compito può essere personalizzato per quello studente, con rimozioni e aggiunte, al punto in cui il corso originale può essere irriconoscibile.

Nelle mie soluzioni, ciò che risulta è:

Al momento dell'assegnazione di un corso a uno studente, il corso viene caricato in memoria. Quindi, per ciascun oggetto secondario, viene generato un oggetto relazione studente / oggetto secondario con i metadati appropriati. In sostanza, sto usando l'oggetto originale come modello per generare gli oggetti personalizzabili richiesti.

Ciò si traduce in un'enorme quantità di dati man mano che gli oggetti secondari diventano più complessi e numerati. Mi chiedo se ci sia qualche ottimizzazione o modello per ridurre la quantità di logica / complessità richiesta per manipolare questo modello di dati.


2
Sei sicuro di voler "ridurre la quantità di dati"? Sei invece alla ricerca di modi per "ridurre la quantità di codice e logica non banali" che devono essere scritti per implementare il comportamento richiesto? (Noto che la gestione in corso dei dati richiede una struttura di dati relazionali, simile a un database.)
rwong,

@rwong Sì, "ridurre [ing] la quantità di codice e logica non banali" è il mio obiettivo finale. Per me ciò significa ridurre la complessità dei dati in qualche modo, ma non è necessariamente un requisito. È diventato un modello di dati così comune che mi chiedo se esiste un modo più semplice per gestirlo.
Nicholas Pickering,

1
In linea di principio questa è una versione migliorata di una relazione m: n. Che dire di un titolo come »Come gestire le relazioni complesse con gli oggetti«?
Thomas Junk,

1
Un'enorme quantità di dati non è la stessa di un enorme livello di complessità nei dati. La difficoltà nel gestire ciò che stai costruendo probabilmente crescerà con la complessità più che con il volume.
Walter Mitty,

1
Interessante. Ho lavorato su diverse applicazioni che hanno questo modello, ma mai notato prima che sia un modello. Mi piacerebbe anche vedere modi più semplici di gestire questo tipo di dati.
Jules,

Risposte:


6

Vedo alcune opzioni a seconda di ciò di cui hai bisogno: (1) se ci sono molte istanze uniche che seguono un algoritmo comune, (2) se ci sono molti oggetti simili o genererai oggetti in fase di esecuzione e (3) se si desidera modificare dinamicamente il comportamento dell'oggetto durante l'esecuzione. Nota: è possibile combinare tutti i motivi che menziono qui, se necessario.

  1. Se ogni "secondo tipo di oggetto" è unico ma segue un modello di comportamento simile, è possibile utilizzare Modello modello . Sembra che tu stia facendo questo. Ma per renderlo esplicito, la tua classe base astratta ha programmato un algoritmo generale; alcuni passaggi di questo algoritmo sono implementati nelle classi derivate.

  2. Se creerai molti oggetti o se la creazione di oggetti in fase di runtime è importante per te, puoi utilizzare Factory Pattern .

  3. E se desideri cambiare dinamicamente il comportamento, Stategy Pattern potrebbe funzionare. Ad esempio, se uno studente in un curriculum regolare viene deciso di avere esigenze speciali o di seguire un programma accelerato. Questo funziona componendo lo "studente" di un oggetto che rappresenterebbe una classe base del curriculum. Il curriculum verrebbe assegnato a un curriculum derivato nella costruzione dello studente (che suona strano) e potrebbe essere riassegnato in un altro curriculum derivato in seguito.

(Solo FYI, se si utilizza (3) Pattern di strategia con C ++, sarà necessario Rvalues ​​per la composizione.)

Per archiviare oggetti e secondi oggetti, può valere la pena considerare Iterator Pattern (per scorrere tra loro, aggiungere, eliminare, ordinare, ecc.).

Un buon riferimento è Head First Design Patterns , che copre i motivi che menziono e la loro implementazione. Lavorano in Java.


0

Trovo difficile credere, in presenza di un archivio di dati o persistenza, che avresti bisogno di avere oggetti con questo tipo di profondità in un dato punto di un runtime. Questo è per la GUI di CRUD? In tal caso, suggerirei di cambiare il tuo approccio dall'inizio. IE:

Identifica la sottostruttura necessaria affinché lo Studente mostri, e memorizza con stato il suo indice di origine nel db e aggiorna senza stato quello, andando alla o dalla vista e dal db del backend.


Non sono sicuro di aver capito il tuo suggerimento. Dovrei generare un oggetto secondario vuoto, quindi forzare l'utente in un altro modulo che consente loro di modificare l'oggetto secondario?
Nicholas Pickering,

Sto suggerendo che gli oggetti di per sé non ottengono molto, se tutto ciò che stai facendo è una transazione senza stato tra il loro contenuto e un database back-end. In tal caso, rimuoverli ed eseguire semplicemente la transazione per i dati specifici di ciò che deve affrontare il client.
John P. Feltz,

Modifica: questo può anche significare la creazione di oggetti per catturare quei particolari dati che vengono scambiati, se sei distorto da ORM a causa della loro convenienza a tale riguardo.
John P. Feltz,

A meno che non fraintenda, non penso che nulla del processo possa essere reso apolide. Tutto dipende dal contesto dell'azione dell'utente. Quando un utente crea un oggetto primario, si aspettano che la sottostruttura sia disponibile per la modifica immediata.
Nicholas Pickering,

-1

Un corso personalizzato per ogni studente al punto in cui il corso originale è irriconoscibile suggerisce che il corso originale è semplicemente un riferimento "predefinito". Quello che vorrei fare è creare una classe chiamata CustomizedCourse (o un elenco di essi) e avere quello (o un elenco di quelli) come proprietà di uno studente. Il CustomizedCourse può avere un riferimento al corso originale per l'uso "referenziale", ma il lavoro principale e i dati sarebbero nel CustomizedCourse stesso.


downvoter ti interessa commentare?
frezq,

Non ho votato a fondo (sono il PO), ma sembra che tu stia cercando di descrivere il modello o il modello di strategia che sono già stati descritti in un'altra risposta.
Nicholas Pickering,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.