Uma maneira simples de obter uma aparência de versionamento é entender os membros dos objetos que você está serializando. Se o seu código compreender os vários tipos de dados a serem serializados, você poderá obter uma certa robustez sem fazer muito trabalho.
Digamos que temos um objeto serializado que se parece com isso:
ObjectType
{
m_name = "a string"
m_size = { 1.2, 2.1 }
m_someStruct = {
m_deeperInteger = 5
m_radians = 3.14
}
}
Deve ser fácil de ver que o tipo ObjectType
tem membros de dados chamadas m_name
, m_size
e m_someStruct
. Se você puder fazer um loop ou enumerar membros de dados durante o tempo de execução (de alguma forma), ao ler este arquivo, poderá ler um nome de membro e associá-lo a um membro real dentro da instância do objeto.
Durante essa fase de pesquisa, se você não encontrar um membro de dados correspondente, poderá ignorar com segurança essa parte do arquivo salvo. Por exemplo, digamos que a versão 1.0 de SomeStruct
tivesse um m_name
membro de dados. Em seguida, você faz o patch e esse membro de dados foi removido completamente. Ao carregar seu arquivo salvo, você encontrará m_name
e procurará um membro correspondente e não encontrará correspondência. Seu código pode simplesmente passar para o próximo membro do arquivo sem travar. Isso permite remover membros de dados sem preocupações com a quebra de arquivos salvos antigos.
Da mesma forma, se você adicionar um novo tipo de membro de dados e tentar carregar de um antigo arquivo salvo, seu código poderá não inicializar o novo membro. Isso pode ser utilizado como vantagem: novos membros de dados podem ser inseridos nos arquivos salvos durante o patch manualmente, talvez introduzindo valores padrão (ou por meios mais inteligentes).
Esse formato também permite que os arquivos salvos sejam facilmente manipulados ou modificados manualmente; a ordem na qual os membros dos dados realmente não têm muito a ver com a validade da rotina de serialização. Cada membro é procurado e inicializado independentemente. Isso pode ser um detalhe que adiciona um pouco de robustez extra.
Tudo isso pode ser alcançado através de alguma forma de introspecção de tipo. Você poderá consultar um membro de dados por pesquisa de sequência e saber qual é o tipo real de dados. Isso pode ser alcançado em C ++ usando uma forma de introspecção personalizada, e outros idiomas podem ter recursos de introspecção incorporados.