¿Cuál es un buen diseño para permitir la compatibilidad con versiones anteriores de un tipo de archivo entre diferentes versiones de software?
Por ejemplo, ¿cómo obtiene Microsoft Word 2007, 2010 y 2013, etc.? Para todos los archivos docx abiertos, pero diferentes ediciones pueden guardar más / menos datos y guardar los datos de formas ligeramente diferentes, todo en el mismo tipo de archivo y un El archivo que se guarda en una versión se puede abrir en otra, pero ¿ciertos elementos del archivo pueden no estar disponibles en versiones anteriores?
Quiero decir, la forma realmente obvia de hacerlo es tener algo como
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
.....
}
pero eso parece increíblemente monolítico, no muy extensible y es probable que genere una gran cantidad de código copiado / pegado.
Así que estaba pensando en usar una interfaz base para todas las versiones que define las estructuras inmutables, como el encabezado, que deben estar presentes en el archivo, y los métodos que deben estar disponibles para la serialización / deserialización, y luego la herencia múltiple para que cada La clase de la nueva versión que implementa la interfaz hereda la versión anterior, y solo anula las cosas que han cambiado, ya que el archivo será el mismo, en su mayor parte.
Realmente no me preocupa la estructura del archivo, ya que ya se decidió que usaremos XML, y el esquema inicial ya está decidido. Sin embargo, sin duda habrá cambios en él en el futuro, y solo quiero poder diseñar el código de una manera que facilite acomodar estos cambios.
fuente
Respuestas:
Puede echar un vistazo al formato de archivo PNG y cómo maneja la compatibilidad de la versión. Cada bloque tiene una identificación que describe qué tipo de bloque es, y tiene algunos indicadores que le dicen al software qué hacer si no puede entender esa identificación. Por ejemplo, "no puede leer el archivo si no comprende este bloque", o "puede leer el archivo pero no modificarlo", o "puede modificar el archivo pero debe eliminar este bloque". Para la compatibilidad con versiones anteriores, su software solo necesita manejar la situación cuando los datos esperados no están presentes.
fuente
Una forma de hacerlo puede ser mediante el uso de una clase base y una interfaz con las funciones básicas para el manejo de sus archivos. Luego use clases para cada versión que se extiendan desde la clase base para manejar todos los casos específicos de la versión. Las funciones que pueden cambiar pueden ser virtuales en su clase base de resumen si solo hay implementaciones específicas de la versión. Cuando necesite una clase para manejar el archivo, use una fábrica que obtenga la implementación específica de la versión de la interfaz de manejo de archivos.
fuente
He hecho esto con XML y funciona bien:
Simplemente permita que cualquier elemento en su documento tenga atributos y subelementos (y cuando el orden no es importante, en cualquier orden). A partir de la primera versión del programa: al leer el documento, ignore los atributos y subelementos que no conoce en la versión actual.
En el futuro, cuando agregue una nueva función a una nueva versión del programa, agregue un atributo o subelemento. Las versiones anteriores lo ignorarán. La nueva versión debe verificar la presencia del atributo o subelemento y manejarlo.
Por ejemplo, tiene algunos elementos con textos:
Y en la versión más reciente, le gustaría agregar color al elemento para que agregue el atributo
color
:La versión anterior simplemente ignorará el
color
atributo al abrir el documento. Las nuevas versiones verifican la presencia decolor
atributo y, si no existe, asignan el color predeterminado.Con esta solución simple, tendrá compatibilidad con versiones anteriores y posteriores.
fuente