Domanda

Sto sviluppando una libreria di classi C ++ contenente classi di modelli di dominio e vorrei aggiungere il supporto per creare un'istanza di queste classi da vari meccanismi di persistenza, ad esempio database e file. L'utente della libreria di classi dovrebbe avere un'interfaccia (?) Con cui programmare una classe in grado di trasferire i dati dal / al meccanismo di persistenza.

Conosco il modello di oggetti di accesso ai dati che sembra funzionare per Java, ma non sono esattamente sicuro di come applicarlo al C ++. Ci sono altre soluzioni?

È stato utile?

Soluzione

C ++ supporta l'ereditarietà multipla in modo da poter avere un'API di persistenza generica ed ereditare un meccanismo di persistenza. Ciò dovrebbe comunque utilizzare l'introspezione per ottenere i metadati della classe, ma si avrebbe comunque questo problema con qualsiasi livello di persistenza.

In alternativa potresti fare qualcosa di simile ma usare i metadati per guidare un generatore di codice che riempia i "Getter" e "Setter" per il livello di persistenza.

Qualsiasi livello di persistenza generalmente usa l'uno o l'altro approccio, quindi il tuo problema è agganciare il meccanismo di caricamento nel livello di persistenza. Penso che questo renda il tuo problema un po 'diverso da un singolo livello di persistenza ma affrontandolo dall'altra parte. Invece di creare classi di dominio su un framework di persistenza, stai fornendo un insieme di classi di dominio con gli hook per un framework di persistenza in cui terze parti possono collegare il loro meccanismo di accesso ai dati.

Penso che una volta fornito l'accesso ai metadati e ai callback della classe il meccanismo di perisistenza sia relativamente semplice. Osserva i componenti dei metadati di qualsiasi comodo framework di mappatura C / O C e scopri come funzionano. Incapsula questo con un'API in una delle classi di base delle tue classi di dominio e fornisci un'API getter / setter generica per l'istanza o la persistenza. Il resto spetta alla persona che implementa il livello di persistenza.

Modifica: Non riesco a pensare a una libreria C ++ con il tipo di meccanismo di persistenza collegabile che stai descrivendo, ma ho fatto qualcosa in Python che avrebbe potuto aggiungere questo tipo di funzione. La particolare implementazione utilizzava le funzionalità in Python senza un equivalente C ++ diretto, sebbene il principio di base potesse probabilmente essere adattato per funzionare con C ++.

In Python, puoi intercettare gli accessi alle variabili di istanza sovrascrivendo __getattr () __ e __setattr () __ . Il meccanismo di persistenza ha effettivamente mantenuto la propria cache di dati dietro le quinte. Quando la funzionalità è stata miscelata nella classe (eseguita tramite ereditarietà multipla), ha annullato il comportamento di sistema predefinito per l'accesso dei membri e ha verificato se l'attributo da interrogare corrispondeva a qualcosa nel suo dizionario. In questo caso, la chiamata è stata reindirizzata per ottenere o impostare un elemento nella cache di dati.

La cache aveva metadati propri. Era a conoscenza delle relazioni tra entità all'interno del suo modello di dati e sapeva quali nomi di attributi intercettare per accedere ai dati. Il modo in cui ha funzionato lo ha separato dal livello di accesso al database e avrebbe potuto (almeno in teoria) consentire l'utilizzo del meccanismo di persistenza con driver diversi. Non vi è alcun motivo intrinseco che non si possa (ad esempio) creare un driver che lo abbia serializzato in un file XML.

Far funzionare qualcosa di simile in C ++ sarebbe un po 'più complicato e potrebbe non essere possibile rendere l'accesso alla cache degli oggetti trasparente come con questo sistema. Probabilmente saresti meglio con un protocollo esplicito che carica e scarica lo stato dell'oggetto nella cache. Il codice per questo sarebbe abbastanza suscettibile alla generazione dai metadati della cache, ma questo dovrebbe essere fatto al momento della compilazione. Potresti essere in grado di fare qualcosa con i modelli o sovrascrivendo l'operatore - > per rendere il protocollo di accesso più trasparente, ma questo probabilmente è più un problema di quanto valga la pena.

Altri suggerimenti

Boost Serialization offre alcune cose utili per lavorare con la serializzazione di tipi C ++, ma quanto corrisponderà all'interfaccia che desideri non lo so. Supporta design intrusivi e non intrusivi, quindi è piuttosto flessibile.

Eviterei la serializzazione, IMHO, l'abbiamo implementata per una delle nostre applicazioni in MFC nel 1995, eravamo abbastanza intelligenti da usare il versioning indipendente degli oggetti e il versioning dei file, ma alla fine si ottiene un sacco di vecchio codice disordinato dopo il tempo.

Immagina determinati scenari, deprecare le classi, deprecare i membri, ecc., Ognuno presenta un nuovo problema. Ora usiamo compressi " tipo XML " flussi, possiamo aggiungere nuovi dati e mantenere la retrocompatibilità.

La lettura e la scrittura del file viene sottratta dalla mappatura dei dati agli oggetti, ora possiamo cambiare i formati dei file, aggiungere importatori / esportatori senza modifiche ai nostri oggetti di business principali.

Detto questo, alcuni sviluppatori adorano la serializzazione, i miei incontri sono che il cambio di base di codice, piattaforme, lingue, toolkit porta con sé molti problemi, la lettura e la scrittura dei dati non dovrebbe essere uno di questi.

Inoltre, l'utilizzo di un formato dati standard, con una chiave proprietaria, significa che è molto più facile lavorare con terze parti.

Potresti dare un'occhiata a aumentare la serializzazione . Non averlo usato non posso dire se raccomandarlo o no. Le librerie boost sono in genere di alta qualità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top