Каков хороший дизайн для обеспечения обратной совместимости типов файлов между различными версиями программного обеспечения?
Например, как Microsoft получает Word 2007, 2010 и 2013 и т. Д. Во все открытые файлы DOCX, но разные редакции могут сохранять больше / меньше данных и сохранять данные немного по-разному, все в один и тот же тип файла, и файл, сохраненный в одной версии, можно открыть в другой, но некоторые элементы файла могут быть недоступны в более старых версиях?
Я имею в виду, что действительно очевидный способ сделать это -
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
.....
}
но это кажется невероятно монолитным, не очень расширяемым и может привести к большому количеству копируемого / вставляемого кода.
Поэтому я думал об использовании базового интерфейса для всех версий, который определяет неизменяемые структуры, такие как заголовок, которые должны присутствовать в файле, и методы, которые должны быть доступны для сериализации / десериализации, а затем множественное наследование, чтобы каждый Класс новой версии, который реализует интерфейс, наследует старую версию и переопределяет только то, что изменилось, поскольку файл по большей части будет таким же.
Меня не очень беспокоит структура файла, так как он уже решил, что мы будем использовать XML, и исходная схема, в общем, уже определена. Тем не менее, в будущем, без сомнения, в него будут внесены изменения, и я просто хочу иметь возможность разрабатывать код таким образом, чтобы облегчить адаптацию к этим изменениям.
источник
Ответы:
Вы могли бы взглянуть на формат файла PNG и как он обрабатывает совместимость версий. У каждого блока есть идентификатор, описывающий, какой это тип блока, и у него есть некоторые флаги, которые указывают программному обеспечению, что делать, если оно не может понять этот идентификатор. Например, «вы не можете прочитать файл, если вы не понимаете этот блок», или «вы можете прочитать файл, но не можете изменить его», или «вы можете изменить файл, но вы должны удалить этот блок». Для обеспечения обратной совместимости вашему программному обеспечению просто необходимо справиться с ситуацией, когда ожидаемые данные отсутствуют.
источник
Для этого можно использовать базовый класс и интерфейс с основными функциями для обработки вашего файла. Затем используйте классы для каждой версии, которые выходят из базового класса, чтобы обрабатывать все случаи, зависящие от версии. Функции, которые могут изменяться, могут быть виртуальными в вашем базовом классе abstract, если существуют только реализации, зависящие от версии. Когда вам нужен класс для обработки файла, используйте фабрику, которая получает специфичную для версии реализацию интерфейса обработки файлов.
источник
Я сделал это с XML, и он работает хорошо:
Просто разрешите любому элементу в вашем документе иметь любые атрибуты и любые подэлементы (а когда порядок не важен - в любом порядке). Начиная с первой версии программы - при чтении документа игнорируйте атрибуты и подэлементы, которые вы не знаете в текущей версии.
В будущем, когда вы добавляете новую функцию в новую версию программы, добавьте атрибут или подэлемент. Старые версии будут игнорировать это. Новая версия должна проверять наличие атрибута или подэлемента и обрабатывать его.
Например, у вас есть некоторые элементы с текстом:
И в более новой версии вы хотели бы добавить цвет к элементу, чтобы вы добавили атрибут
color
:Старая версия просто игнорирует
color
атрибут при открытии документа. Новые версии проверяют наличиеcolor
атрибута и, если не существует, назначают цвет по умолчанию.С этим простым решением у вас будет как обратная, так и прямая совместимость.
источник