Лучший способ хранить данные приложения, когда данные хранятся и формат данных может измениться в будущих версиях? - PullRequest
1 голос
/ 04 марта 2010

Я делаю игру для Android на Android (хотя этот вопрос действительно относится ко всем языкам) и надеюсь выпустить первую версию в ближайшее время. Я нервничаю из-за того, как я сохраняю данные в моей игре. Моя проблема в том, что, если в более позднем обновлении я решу сохранить больше данных или сохранить те же данные другим способом, мне нужно быть осторожным, чтобы не потерять или не испортить данные для пользователей, которые обновляются (т.е. я хочу, чтобы пользователи быть в состоянии использовать данные, созданные старой версией в новой версии, например, их высокие оценки, полученные ранее).

Например, скажем, я хочу сохранить рекорды в версии 1, и я использую такой класс, как:

class Score { String name; int score; }

Затем я сохраняю результаты в ArrayList, а затем, чтобы сохранить / загрузить результаты, я сериализую объект ArrayList.

В версии 1.1, возможно, я решу, что хочу сохранить дату с каждым счетом. Затем я мог бы обновить объект Score, включив в него поле даты и использовать значения по умолчанию для даты, если старый объект не содержит дату.

В версии 1.2, возможно, я решу, что вместо этого я хочу хранить оценки в TreeSet, а в версии 1.3, возможно, я хочу также загружать / хранить оценки онлайн.

В любом случае, я хочу сказать, есть ли какие-нибудь общие советы, как облегчить мне жизнь здесь? Я особенно обеспокоен ситуациями из вышеперечисленного, когда один человек обновляет с версии 1.1 до 1.2 и один человек обновляет с 1.0 до 1.2. Тестирование всех сценариев на предмет повреждения данных звучит как головная боль.

Неужели это действительно сложный случай, чтобы выбрать что-то разумное и масштабируемое для начала?

Я думаю, что было бы легко использовать HashMap из String-> Object в качестве объекта хранения общего назначения, например. storage.put ("HighScoreName1", "Bob"); storage.put ("HighScorePoints1", 15) ;. Получение информации немного сложнее, чем если бы я использовал пользовательский класс, но, кажется, легко добавить дополнительные поля и так далее без особой работы. Перебор списков, сохраненных таким образом, не очень хорош.

Ответы [ 3 ]

2 голосов
/ 04 марта 2010

Если вы используете SQLiteOpenHelper, взгляните на метод onUpgrade .

Вызывается, когда база данных должна быть модернизированы. Реализация должна используйте этот метод, чтобы удалить таблицы, добавить таблицы, или делать что-то еще, что ему нужно обновить до новой версии схемы.

2 голосов
/ 04 марта 2010

Запишите номер версии в свой выходной поток, прежде чем писать сериализованный контент. Я также предлагаю записать последовательность магических строк в начало потока (просто то, что вы можете сказать, принадлежит вам - может быть, 5 или 6 символов). Итак, вы напишите MAGIC, а затем напишите свой номер версии. Затем вы напишите свой сериализованный контент.

Чтение с диска довольно просто - прочитайте и подтвердите магию. Читать версию Десериализовать, а затем передать десериализованный контент обработчику на основе магии.

Здесь пара слов предостережения: если возможно, сохраняйте классы, которые вы используете в сериализованном потоке, простыми (String, Integer и т. Д.). Если вы используете свои собственные классы, вы должны быть безумно осторожны, чтобы вам никогда не приходилось проводить рефакторинг таким образом, чтобы это изменило пакет или имя класса.

Как бы заманчиво ни было просто записать свои бизнес-объекты в хранилище с использованием сериализации, в долгосрочной перспективе это почти всегда ошибка. Вместо этого я настоятельно рекомендую разработать объект конфигурации. Ваше приложение инициализирует себя из объекта конфигурации. Когда пришло время для сохранения, приложение создает объект конфигурации. Тогда вы никогда и никогда не меняете класс конфигурации после его доставки. Просто создайте новый (подклассы в порядке).

Разделив чтение и запись объектов конфигурации, вы можете довольно легко сделать следующее:

  1. Считать старую конфигурацию
  2. Инициализация приложения со старой конфигурацией Позже ...
  3. Приложение создает новую конфигурацию
  4. Запись новой конфигурации в файл

presto - мгновенное обновление формата файла.

Очевидно, что с такими большими и сложными графами данных это сложно (в любом случае много), но вы говорите об Android, так что ваше постоянное состояние, вероятно, не так уж сложно.

Обратите внимание, что сохранение в формате XML или даже в базе данных SQL - это просто другая форма вышеуказанной стратегии.

1 голос
/ 04 марта 2010

Определенного ответа нет, но термин, который вы ищете, - это версия. В лучших реализациях сериализации (и форматах файлов) это может работать в обоих направлениях (старые версии приложения могут читать файлы новых версий и наоборот).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...