Содержание
Проблема описания данных стоит перед создателем практически любого приложения. Вне зависимости от того, какова природа данных; вне зависимости от того, должно ли приложение их создавать и изменять или данные используются только для чтения; передаются данные по сети или существуют на жестком диске – они должны храниться в достаточно удобном формате.
Удобство формата определяется тем, насколько легко можно реализовать загрузку и сохранение данных, насколько большие накладные расходы по объему и скорости чтения влечет за собой его использование и насколько выбранный формат удобен для отладки (т.е. насколько он читаем человеком и насколько адекватные сообщения об ошибках в данных способен выдать загружающий их код).
Помимо вышеперечисленного, для удобства использования немаловажен объем имеющихся наработок по данному формату – наличие сторонних и собственных библиотек, средств перевода «живых» объектов логики приложения в сохраненные данные и обратно и проч. (сериализации, англ. serialization; для краткости в рамках статьи будем назвать сериализацией весь процесс – и сохранение, и загрузку объектов, хотя, формально, загрузку следует называть десериализацией) и проч. Такие средства могут предоставлять разную степень интеграции с логикой программы – от API для создания, сохранения, загрузки и модификации «голых» данных до инструментария тесной интеграции, позволяющего сериализовать объекты логики без написания промежуточного кода работы с форматом данных.
В отличие от данных, для хранения которых существуют устоявшиеся форматы, как, например, видео (AVI, WMV…), музыка (MP3, OGG…) или документы (DOC, PDF…), для данных, специфичных для логики конкретного приложения в общем случае разработчик должен создать формат хранения самостоятельно (хотя некоторые средства разработки и языки программирования упрощают этот процесс вплоть до полной автоматизации). При этом зачастую одному приложению требуются несколько различных форматов хранения для разных наборов данных.
Как и всегда, разработка формата хранения данных с нуля чревата многими проблемами. Поскольку сериализация объектов логики обычно не предъявляет экстремальных требований к эффективности по скорости и объемам данных, лучше использовать одно из обобщенных решений – создать конкретный формат при помощи некоего готового «метаформата» и связанного с ним набора технологий.
Существующие решения
Самое распространенное на данный момент «обобщенное» решение – использование языка XML. Вокруг этого языка существует огромная развитая как в плане технологий, так и в плане инструментария инфраструктура. Широчайшая распространенность и связанные с этим бонусы – главное преимущество XML.
Однако у XML существует ряд недостатков. Основной из них – избыточность, увеличивающая объем занимаемый данными, замедляющая процесс чтения и записи данных и усложняющая их ручное редактирование. Эта избыточность усугубляется тем, что XML – сугубо текстовый формат (впрочем, имеется несколько нестандартизованных вариантов Binary XML).
Помимо XML, в динамических языках (Python, Ruby и т.д.) получила распространения технология YAML (www.yaml.org). В языках программирования, ориентированных на веб-разработку, нередко используется JSON (JavaScript Object Notation, www.json.org). Обширный список альтернатив XML можно изучить по адресу www.pault.com/pault/pxml/xmlalternatives.html.
В данной статье будет рассказано о еще одном подходе к хранению данных, основанном на применении языка Lua.
Lua – расширяемый скриптовой язык расширений (extensible extension language) с динамической типизацией. Код в статье написан на наиболее свежей версии языка – 5.1, но должен работать и на предыдущей 5.0. Руководство по языку и первое издание книги одного из авторов языка – Роберто Иерусалимского (Roberto Ierusalimschy) Programming in Lua можно найти в электронном виде на официальном сайте (www.lua.org).
Выгода от применения описываемого подхода удваивается, когда в приложении существует потребность во встроенном скриптовом языке – подключение Lua к коду на C, C++ (а также любом языке, имеющем интерфейс в заимодействия с C – например, существует интерфейс Lua-Python) достаточно легко. При этом и для хранения данных и для задания конечной логики приложения используется один и тот же язык, что упрощает процесс освоения системы.
Наиболее ярко это проявляется в компьютерных играх. Язык Lua вообще получил наибольшее распространение именно в этой области во многом благодаря своей скорости, мощности, гибкости и легкости подключения к коду приложения. Однако, помимо компьютерных игр, Lua широко используется и в других областях – от средства для профессиональной работы с фотографиями (например, до сорока процентов кода Adobe Lightroom написано на Lua, labs.adobe.com/technologies/lightroom/) до системы обработки данных о геноме человека, использующей Lua для хранения огромных объемов данных (www.cbrc.jp/~ueno/slides/lua05u3.pdf). Постоянно растущий список проектов, использующих Lua, можно найти на официальном сайте языка (www.lua.org/uses.html).
В разрабатывавшемся при участии автора проекте (движок, на котором выпущено несколько игр в жанре quest/adventure) форматы данных, основанные на описываемом подходе, используются для таких данных, как описания пользовательского интерфейса, игрового мира, структуры игровых ресурсов и т.п. Нужно отметить, что, несмотря на то, что конкретные примеры в статье взяты из области разработки компьютерных игр, сам описываемый подход безусловно применим и в других областях разработки программного обеспечения.
Часть 2