Bezdepbonusu7Программирование: статьи и ответы

Упростите свое хранилище в Xamarin с помощью SimpleStorage

Архив Bezdepbonusu74 мин чтения

При разработке мобильного приложения важно учитывать архитектуру хранения данных, которая наилучшим образом соответствует потребностям приложения. Во многих случаях, особенно если приложение интенсивно использует данные, база данных является лучшим вариантом. У меня был большой опыт использования пакета SQLite.NET для Xamarin, в частности. Однако в некоторых случаях база данных не является лучшим вариантом для хранения данных. Например, простое хранилище ключ-значение часто является отличным решением для небольших фрагментов данных, таких как пользовательские настройки и настройки приложения, которые можно легко получить с помощью уникального ключа.

Введение в SimpleStorage

SimpleStorage - это кроссплатформенная реализация хранилища данных типа ключ-значение, использующая собственный API-интерфейс Preferences каждой платформы. Для iOS это означает NSUserDefaults, а для Android - SharedPreferences.

SimpleStorage предоставляет простой синхронный API. Это упрощает хранение произвольных пар данных "ключ-значение" как в iOS, так и в Android. SimpleStorage также использует метод двоичной сериализации, который позволяет сериализовать объекты на диск и десериализовать их при обратном считывании. Это упрощает хранение произвольных объектов, как встроенных (например, DateTime), так и пользовательских. Я рекомендую SimpleStorage как надежное, простое и легко интегрируемое решение для вашего проекта Xamarin.

Некоторые ключевые расширения

При использовании SimpleStorage в моем последнем проекте я заметил, что ему не хватает нескольких ключевых функций. Среди них были возможности:

  • Получить все ключи в заданной группе хранения
  • Получить все группы хранения
  • Получение полной группы хранения за один раз

В частности, невозможность получить все ключи была для меня препятствием. Я решил реализовать этот функционал как расширение для SimpleStorage.

Желаемые интерфейсы

Я хотел сохранить интерфейс, аналогичный реальному SimpleStorage, в своем классе-оболочке. Поскольку мы работаем на C#, я решил создать интерфейс IPersistentStorage для определения API этого модуля. Использование интерфейса также позволяет нам реализовать другую версию этих расширений для работы с модульными тестами (мы увидим это позже).

See the code in the full post.

Этот интерфейс похож на SimpleStorage API, за исключением нескольких отличий. Первое отличие - это свойство Groups. Этот API вернет IEnumerable всех имен групп хранения. Следующее отличие - метод KeysForGroup, возвращающий список ключей для данной группы хранения. Наконец, последнее большое отличие - API GetGroup, который возвращает словарь всех пар ключ-значение для данной группы хранения. Это действительно отличный метод полезности в некоторых ситуациях.

Реализация расширений

Основа реализации основана на частной структуре словаря, которая используется внутри для хранения групп и их ключей. Это реализовано как ConcurrentDictionary, чтобы обеспечить потокобезопасное манипулирование структурой. Ниже приведено определение класса и конструктор:

See the code in the full post.

Конструктор инициализирует словарь groupMappings на основе сохраненной схемы хранилища значений ключа. Схема обновляется по мере добавления и удаления ключей, что вы увидите чуть позже. Группа схемы хранит список групп хранения. Тогда у каждой группы хранения будет соответствующая группа хранения *Keys, которая содержит все ключи, связанные с этой группой. С помощью обеих этих предопределенных структур данных мы можем реконструировать наши группы хранения и соответствующие им ключи.

Теперь, когда мы определили базовую архитектуру, следующим шагом будет реализация отдельных интерфейсов. В некоторых случаях реализация обернутого метода проста: просто переход к эквиваленту SimpleStorage. Например, метод Get определен ниже:

See the code in the full post.

В API SimpleStorage вы можете выполнять операции Get/Set/Delete только в контексте объекта SimpleStorage (возвращенного из EditGroup). Этот API-оболочка просто позволяет вызывающей стороне передавать группу и ключ в одном и том же вызове метода, что, на мой взгляд, является хорошей абстракцией.

Однако сложная часть этой реализации заключается в отслеживании сохраняемых групп и ключей. Возьмем, например, метод Set:

See the code in the full post.

Вы заметите вызов метода TryAddGroupAndKey, который в основном принимает комбинацию группы и ключа и пытается добавить новую группу и/или ключ в хранилище. Метод TryAddGroupAndKey определен ниже:

See the code in the full post.

Помимо обновления словаря groupMappings, нам также необходимо обновить ключи для этой группы. Если это новая группа, то нам нужно добавить ее в хранилище схем. Вы можете представить очень похожую (но противоположную) реализацию для TryRemoveGroupAndKey, которая используется в методе Delete. Каждый раз, когда словарь изменяется, мы соответствующим образом обновляем сохраняемую схему, что позволяет нам всегда поддерживать правильную схему хранения. Всю реализацию PersistentStorage можно найти здесь.

Что насчет тестов?

Я также написал реализацию IPersistentStorage для тестирования под названием TestStorage. Вы также можете найти эту реализацию здесь. Эта реализация вообще не поддерживается SimpleStorage, но она хранит локальный словарь групп, ключей и значений в оперативной памяти. Он имеет все те же интерфейсы и функции, что и настоящая версия, но обычно вам не нужно беспокоиться о фактическом сохранении данных во время модульного тестирования.

Ну это все! Я весело провел время, расширяя возможности SimpleStorage, и я надеюсь, что вы узнали кое-что о том, как хранить простые данные пары "ключ-значение" в Xamarin/C#.

Первоначально опубликовано на spin.atomicobject.com 12 сентября 2016 г.

ProgrammingJavaScriptXamarin

Похожие материалы

Статья из архива сайта: перевод и редактура материала сообщества разработчиков. Версии библиотек и инструментов могли измениться, сверяйтесь с официальной документацией.