Яка хороша конструкція для забезпечення зворотної сумісності файлів між різними версіями програмного забезпечення?


14

Яка хороша конструкція для забезпечення зворотної сумісності типу файлів між різними версіями програмного забезпечення?

Наприклад, як Microsoft отримує слова 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, і початкова схема, за великим рахунком, вже вирішена. Однак в майбутньому, без сумніву, не буде змін, і я просто хочу мати можливість спроектувати код таким чином, щоб легко змінити ці зміни.


6
Ви повинні розробити формат файлу таким чином, щоб він не ігнорував інформацію, якої не вистачає, оскільки джерело є з більш ранньої версії, але і інформацію, яку він не очікує, оскільки джерело з нової версії. Якщо ви починаєте з нуля, будь ласка, будь ласка, також просувайте сумісність . Це майже не вимагає додаткових зусиль та збільшує корисність вашого програмного забезпечення.
Кіліан Фот

Чи завжди ви завжди будете знати, напевно (з заголовка), з якою версією файлу ви маєте справу? Також, щоб подати ще один запит, будь ласка, перевірте наявність пошкоджених чи шкідливих файлів і не дозволяйте їм викликати проблеми. Ваші сисадміни будуть вам вдячні :).
cxw

1
Так, номер версії завжди буде в заголовку файлу, а формат заголовка ніколи не зміниться. Ми ідемо з тим, що файли, створені між незначними версіями програмного забезпечення, повинні бути сумісними, тобто файл, створений в v1.1, можна відкрити в v1.2 і навпаки, хоча деякі функції з 1.2 можуть бути відсутніми в 1.1, але основні версії порушить сумісність вперед, тому речі, записані в v2, не відкриються в v1, але речі, написані в v1, відкриються в v2.
JJBurgess

Що ж стосується корупції, то файли містять DSL, а програма, що відкриває / закриває їх, - це власний внутрішній IDE / компілятор. Вони не збираються ніде поблизу виробничого середовища, тому адміністратор не повинен турбуватися.
JJBurgess

Відповіді:


10

Ви можете ознайомитись із форматом файлу PNG та способом обробки сумісності версій. Кожен блок має ідентифікатор, що описує тип блоку, і він містить деякі прапори, які повідомляють програмному забезпеченню, що робити, якщо він не може зрозуміти цей ідентифікатор. Наприклад, "ви не можете прочитати файл, якщо ви не розумієте цього блоку", або "ви можете прочитати файл, але не змінити його", або "ви можете змінити файл, але вам потрібно видалити цей блок". Для зворотної сумісності вашому програмному забезпеченню потрібно просто впоратися з ситуацією, коли очікуваних даних немає.


Чудова ідея! Формат PNG покладається на функції, а не на версії. Однак це означає, що основний формат ніколи не повинен змінюватися. (тобто заголовок, що визначає особливість.)
Флоріан Маргайн

Це цікаво. Я зараз читаю специфікацію файлу. Мені подобається ідея критичних та допоміжних шматочків, і я можу спробувати це попрацювати.
JJBurgess

3

Спосіб зробити це можна за допомогою базового класу та інтерфейсу з основними функціями для обробки файлів. Потім використовуйте класи для кожної версії, яка поширюється на базовий клас, щоб обробити всі конкретні випадки версії. Функції, які можуть змінюватися, можуть бути віртуальними у базовому класі реферату, якщо існують лише конкретні версії. Коли вам потрібен клас для обробки файлу, використовуйте фабрику, яка отримує реалізовану для версії інтерфейс обробки файлів.


Єдине моє питання з цим полягає в тому, що ви в кінцевому підсумку дублюєте конкретну версію для кожної наступної версії. Скажімо, у вас є три методи базового класу: ReadNames (), ReadAges () та ReadAddresses (), а у V2 класу ви вносите зміни до ReadAges (). Якщо у V3 ви вирішите внести зміни до ReadNames (), якщо всі ваші класи, визначені для версії, успадковуються від бази, ви втратите зміни V2 або вам потрібно буде скопіювати / вставити зміни з V2 в реалізацію V3.
JJBurgess

1
Реалізація читань може викликати інший клас, який містить фактичну реалізацію щодо того, як читати віки для цієї версії. Створення вашого класу буде більше конфігурацією інтерфейсів / заводів, ніж власне програмування.
одноліткові

2

Я зробив це з XML, і він працює добре:

Просто дозвольте будь-якому елементу у вашому документі мати будь-які атрибути та будь-які підпункти (і коли порядок не важливий - у будь-якому порядку) Починаючи з першої версії програми - під час читання документа ігноруйте атрибути та піделементи, про які ви не знаєте в поточній версії.

Надалі, коли ви додаєте нову функцію до нової версії програми, тоді додайте атрибут або під елемент. Старіші версії ігнорують його. Нова версія повинна перевірити наявність атрибута чи піделемента та обробити його.

Наприклад, у вас є деякі елементи з текстами:

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

І в новій версії ви хочете додати колір до елемента, щоб додати атрибут color:

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

Старіша версія просто ігнорує colorатрибут при відкритті документа. Нові версії перевіряють наявність colorатрибута, а якщо його немає, призначає колір за замовчуванням.

За допомогою цього простого рішення ви матимете сумісність як назад, так і вперед.


Невелика проблема з цим "простим" варіантом полягає в тому, що ви будете знімати всі несподівані атрибути (або залишати їх незмінними) під час збереження документа. Як було сказано в інших відповідях, краще рішення хоча б визначає агностичний спосіб у якійсь версії щодо того, чи повинен атрибут бути відкинутим, збереженим або спричинити, що документ стане лише для читання для версій, які його не розуміють.
Марк Херд

@Mark Hudr: Так, я мовчки припускаю, що зворотна сумісність повинна бути, а сумісність вперед - це бонус. Коли хтось відкриває новий документ у старій версії додатків, він не повинен дивуватися, що, зберігаючи його, вони втратили щось, що вже не видно в старому додатку. Додаткова логіка здається мені переосмисленою.
користувач3123061
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.