Una manera simple de lograr una apariencia de control de versiones es dar sentido a los miembros de los objetos que está serializando. Si su código comprende los diversos tipos de datos que se van a serializar, puede obtener cierta solidez sin hacer demasiado trabajo.
Digamos que tenemos un objeto serializado que se ve así:
ObjectType
{
m_name = "a string"
m_size = { 1.2, 2.1 }
m_someStruct = {
m_deeperInteger = 5
m_radians = 3.14
}
}
Debería ser fácil ver que el tipo ObjectType
tiene miembros de datos llamados m_name
, m_size
y m_someStruct
. Si puede recorrer o enumerar miembros de datos durante el tiempo de ejecución (de alguna manera), al leer este archivo, puede leer el nombre de un miembro y compararlo con un miembro real dentro de su instancia de objeto.
Durante esta fase de búsqueda, si no encuentra un miembro de datos coincidente, puede ignorar con seguridad esta parte del archivo guardado. Por ejemplo, la versión 1.0 de SomeStruct
tenía un m_name
miembro de datos. Luego parches y este miembro de datos se eliminó por completo. Al cargar su archivo guardado, encontrará m_name
un miembro coincidente y no encontrará ninguna coincidencia. Su código simplemente puede pasar al siguiente miembro del archivo sin fallar. Esto le permite eliminar miembros de datos sin preocuparse por romper viejos archivos guardados.
Del mismo modo, si agrega un nuevo tipo de miembro de datos e intenta cargar desde un archivo de guardado anterior, es posible que su código no inicialice al nuevo miembro. Esto se puede utilizar para una ventaja: los nuevos miembros de datos se pueden insertar en los archivos guardados durante la aplicación de parches manualmente, quizás introduciendo valores predeterminados (o por medios más inteligentes).
Este formato también permite manipular o modificar fácilmente los archivos guardados a mano; El orden en que los miembros de datos realmente no tiene mucho que ver con la validez de la rutina de serialización. Cada miembro se busca e inicializa de forma independiente. Esto podría ser un detalle que agrega un poco de robustez adicional.
Todo esto se puede lograr a través de alguna forma de introspección de tipo. Deberá poder consultar a un miembro de datos mediante la búsqueda de cadenas y poder saber cuál es el tipo de datos real del miembro de datos. Esto se puede lograr en C ++ utilizando una forma de introspección personalizada, y otros lenguajes pueden tener incorporadas instalaciones de introspección.