Qual è un buon design per consentire la retrocompatibilità dei file tra diverse versioni del software?

13

Che cos'è un buon design per consentire la retrocompatibilità di un tipo di file tra diverse versioni del software?

Ad esempio, come ottiene Microsoft Word 2007, 2010 e 2013 ecc. a tutti i file docx aperti, ma diverse edizioni possono salvare più / meno dati e salvare i dati in modi leggermente diversi, tutti con lo stesso tipo di file e un file salvato in una versione può essere aperto in un'altra, ma alcuni elementi del file potrebbero non essere disponibili nelle versioni precedenti?

Voglio dire, il modo davvero ovvio per farlo è avere qualcosa di simile

private string openfile(string filename)
{
    File.Open(filename)

    ... some logic that gets a header from the file that will never change

    switch (fileversion)
        case 2007:
            .....
        case 2010
            .....
        case 2013
            .....
}

ma sembra incredibilmente monolitico, non molto estensibile e probabilmente porterà a molto codice copia / incollato.

Quindi stavo pensando di usare un'interfaccia di base per tutte le versioni che definiscono le strutture immutabili, come l'intestazione, che devono essere presenti nel file, e i metodi che devono essere disponibili per la serializzazione / deserializzazione, quindi l'ereditarietà multipla in modo che ogni classe della nuova versione che implementa l'interfaccia erediti la vecchia versione e sostituisca solo le cose che sono cambiate, poiché il file sarà lo stesso, per la maggior parte.

Non mi preoccupo molto della struttura del file, dal momento che è già stato deciso che useremo XML, e lo schema iniziale è, in linea di massima, già deciso. Tuttavia, in futuro ci saranno senza dubbio delle modifiche ad esso, e voglio solo essere in grado di progettare il codice in un modo che faciliti l'adattamento di questi cambiamenti.

    
posta JJBurgess 03.07.2015 - 10:04
fonte

3 risposte

10

Potresti dare un'occhiata al formato del file PNG e al modo in cui gestisce la compatibilità della versione. Ogni blocco ha un id che descrive che tipo di blocco è, e ha alcune bandiere che dicono al software cosa fare se non riesce a capire che id. Ad esempio "non puoi leggere il file se non capisci questo blocco" o "puoi leggere il file ma non modificarlo" oppure "puoi modificare il file ma devi eliminare questo blocco". Per compatibilità con le versioni precedenti, il tuo software deve solo gestire la situazione quando non sono presenti dati previsti.

    
risposta data 03.07.2015 - 14:37
fonte
3

Un modo per farlo può essere utilizzando una classe base e un'interfaccia con le funzioni di base per la gestione dei file. Quindi utilizzare le classi per ogni versione che si estende dalla classe base per gestire tutti i casi specifici della versione. Le funzioni che possono cambiare possono essere virtuali nella tua classe base astratta se esistono solo implementazioni specifiche della versione. Quando hai bisogno di una classe per gestire il file, utilizza una factory che ottiene l'implementazione specifica della versione dell'interfaccia di gestione dei file.

    
risposta data 03.07.2015 - 10:27
fonte
2

Ho fatto questo con XML e funziona bene:

Permetti semplicemente a qualsiasi elemento del tuo documento di avere attributi e sottoelementi (e quando l'ordine non è importante - in qualsiasi ordine). A partire dalla prima versione del programma - durante la lettura del documento, ignorare attributi e sotto-elementi che non si conoscono nella versione corrente.

In futuro, quando aggiungi nuove funzionalità alla nuova versione del programma, aggiungi l'attributo o l'elemento secondario. Le versioni precedenti lo ignoreranno. La nuova versione dovrebbe controllare la pressione di attributo o sottoelemento e gestirla con esso.

Ad esempio hai alcuni elementi con testi:

<item text="Hello, world!"/>

E nella versione più recente vorresti aggiungere un colore all'elemento in modo da aggiungere l'attributo color :

<item text="Hello, world!" color="008000"/>

La versione precedente semplicemente ignorerà l'attributo color all'apertura del documento. Le nuove versioni verificano la presenza di un attributo color e se non esiste assegna il colore predefinito.

Con questa semplice soluzione avrai sia la compatibilità a ritroso che a ritroso.

    
risposta data 06.07.2015 - 10:50
fonte

Leggi altre domande sui tag