Progettazione dell'accesso al "database" basato su file

3

È capitato frequentemente di dover fornire l'accesso a un gruppo di file organizzati in un albero di directory in base ad alcune regole (talvolta non specificate). Il mio modello standard prevede di fornire una classe Database che viene inizializzata con la directory root. Questa classe fornisce i metodi getX () - like (esempio: getStructure ()) per estrarre i dati dal database. Questi metodi normalmente restituiscono oggetti semanticamente significativi (Structure) con metodi appropriati che restituiscono dati (ad esempio structure.getPoints ()). Non sono completamente soddisfatto di questo design, per due motivi principali.

Il primo problema è che la mappatura tra oggetti e file in-applicazioni potrebbe non essere 1: 1, cioè creare l'oggetto Structure potrei dover aprire file diversi nel "database", e la mappatura potrebbe non Sii perfetto. In questo caso, chiamo la Struttura un "oggetto spesso". Un'alternativa ("oggetti sottili") è di attenersi agli oggetti che sono completamente rappresentati in un file, anche se poveri nel significato di dominio di alto livello (cioè se ho due file per definire una struttura , un file contenente punti e l'altro contenente connessioni tra questi punti, fornisco solo un oggetto Points e un oggetto Connections e consento a qualcun altro di "connettere i punti" al di fuori del Database).

L'altro problema che ho è il seguente: chi dovrebbe eseguire l'analisi dei file effettiva? Immagino due strategie: o gli oggetti sono in grado di deserializzare se stessi da file ("pickle-like" in linguaggio python), o sono solo stupidi contenitori di dati riempiti da oggetti parser stateless (uno per file), o anche dall'oggetto database stesso.

Quando si esegue ORM, esistono regole chiare e ben definite su come l'oggetto è rappresentato nel database e il processo è estremamente ben definito in termini di interfaccia e comportamento. Questo non è necessariamente verificato con un gruppo arbitrario di file che alcuni chiamano "database".

Mi piacerebbe davvero i tuoi punti al riguardo. Come devo eseguire la deserializzazione corretta in questo caso di "raw mapping"? Oggetti sottili o spessi? Intelligente o stupido?

Si noti che in realtà non ho alcun controllo quando si tratta dei file che devo accedere. Ottengo i file da fonti esterne e devo convertirli in qualche tipo di oggetti di dominio, in genere solo per la lettura, ma a volte anche per la scrittura. Readonly è di gran lunga il caso più frequente però.

    
posta Stefano Borini 23.02.2012 - 19:31
fonte

3 risposte

3

La chiave qui è disporre di livelli con interfacce ben definite. Lo strato più basso si occupa strettamente dell'accesso fisico ai file. Gestisce cose come il caching, l'accesso simultaneo, l'apertura, il flushing, ecc. La sua interfaccia consente ai livelli superiori di recuperare una riga alla volta senza doversi preoccupare di cose come se il file fosse già aperto.

Il secondo livello fornisce strutture di dati stupide con cui lavorare. La sua interfaccia consisterebbe fondamentalmente in un mucchio di record con colonne di tipi di dati semplici, che sono tutti contenuti in un singolo file. Righe del database, se vuoi.

Il terzo livello fornisce oggetti intelligenti con cui lavorare. Raggruppa le righe del database da più tabelle per creare oggetti con interfacce amichevoli.

    
risposta data 23.02.2012 - 21:10
fonte
2

I call the Structure a "Thick object". An alternative ("thin objects") is to stick to objects that are fully represented in a file, even if poor in high-level domain meaning

Questi non sono esclusivi. Spesso devi fare entrambe le cose.

I problemi relativi al formato fisico e al layout logico sono separati dal dominio problematico. Tre strati.

objects are able to deserialize themselves from file ("pickle-like" in python parlance),

Non funziona bene a lungo termine. La definizione della classe diventa ingombra di problemi di rappresentazione.

Gli oggetti Python non si picchiano. Il decapaggio viene gestito separatamente. A volte una classe deve fornire suggerimenti per il codec all'algoritmo pickle.

dumb data containers filled by stateless parser objects (one per file), or even by the database object itself.

Gli oggetti parser "stateless" non sempre funzionano bene.

I progetti di parser (o di fabbrica o di costruttore) funzionano bene. Basta lasciare "senza stato". Pensa alla scansione lessicale e all'analisi in modo separato rispetto alle rappresentazioni del dominio del problema fisico, logico e finale che potrebbero essere richieste.

How should I perform proper deserialization in this case of "raw mapping"?

Potrebbero essere necessarie classi di formato fisico. Spesso, questi sono già forniti in una libreria di lingue. Non reinventare la ruota.

Thin or thick objects ?

Non è una scelta esclusiva. Hai una disposizione logica e le classi di livello dominio appropriate indipendentemente da qualsiasi rappresentazione fisica.

Smart or dumb ?

Al di fuori del dominio del problema, le classi dovrebbero essere focalizzate sulla rappresentazione. Non lo so, questo li rende stupidi o no.

Mantenere le preoccupazioni separate.

  • Il formato fisico è per CSV, ZIP, XML, JSON, ecc.

  • Il layout logico gestisce le variazioni nei nomi delle colonne, i tipi di dati e la struttura.

  • Il dominio dei problemi è il vero oggetto con cui vuoi lavorare.

risposta data 23.02.2012 - 21:53
fonte
1

Lo faccio serializzando e deserializzando oggetti usando XML. Ciò ti consente di definire le tue regole in base alla struttura delle tue classi.

Alcuni semplici metodi di supporto ToXml() e FromXML() fanno tutto il lavoro pesante.

Quindi, ad esempio:

public class MyRecord
{
    [XmlAttribute]
    public string Foo { get; set; }

    [XmlAttribute]
    public int Bar { get; set }

    [XmlAttribute]
    public double Baz { get; set; }
}

genera un XML che assomiglia più o meno a questo:

<MyRecord Foo="ABC" Bar="123" Baz="123.45">

Puoi renderlo elaborato come vuoi, usando la composizione per nidificare gli oggetti all'interno di altri oggetti, e così via, creando strutture ad albero o anche collezioni.

public class MyRecordTree
{
    public MyRecordTree Node { get; set; }
    public List<MyRecordTree> Children { get; set; }
}
    
risposta data 23.02.2012 - 19:45
fonte

Leggi altre domande sui tag