- PVSM.RU - https://www.pvsm.ru -
В своём развитии мне пришлось пробежаться по нескольким этапам в нескольких направлениях: Java → Objective C → Swift, Web → Enterprise → Mobile, XML → JSON. Этим путём я шёл на протяжении более 15 лет, подолгу и внимательно задерживаясь на каждом этапе. Нужно идти дальше. За мобильными приложениями можно придумать что-то (наверное, пока не хочется), языков вообще пруд-пруди, ничего интереснее JSON'а не придумали. А зачем его менять?
Дальше я расскажу почему мне не очень нравится JSON для некоторых применений и как, по моему мнению, его можно доработать, чтобы стало немного удобнее.
Сразу должен отметить, что не рассматриваю KTV, как замену JSON. И ни в коем случае не рассматриваю его для использования в JavaScript'е. Это будет неудобно и неправильно. С другой стороны, ситуация, когда система описания объектов JavaScript'а используется в других языках для работы с типизированными данными — тоже странная, и её хочется поправить.
Сам по себе JSON хороший.
Болезни JSON'а растут из истории создания. Нужно было, чтобы eval(что-то)
в JavaScript'е выдавал объект, с которым удобно работать. К сожалению, eval'ы в других языках работают обычно по-другому (если вообще присутствуют), и сами языки отличаются. Используя этот формат с не-JavaScript, видны его недостатки.
Я попробовал найти формат, который бы работал как JSON (в идеале — являлся бы его надмножеством), но при этом умел стандартным образом решать часть или все перечисленные выше проблемы. Нашёл YAML.
YAML хорош. Он почти надмножество JSON, хорошо определён (http://www.yaml.org/spec/1.2/spec.html [2]), легко читается. Но вместе с тем:
В общем, YAML «не пошёл». Кроме него популярных форматов я не знаю. Если вдруг вы знаете — пишите, с удовольствием посмотрю.
Пришло время представить то, что получилось у меня.
Key-Type-Value. Я так называю этот формат.
Напишем простой объект на JSON'е:
{
"name": "Alex",
"coolness": 3.1415,
"isAProgrammer": true
}
Если переписать это же на KTV, получится:
{
name: Alex
coolness: 3.1415
isAProgrammer: true
}
Казалось бы, ничего не поменялось. Но давайте присмотримся:
И первый и второй примеры — оба являются корректными KTV-файлами. Это очень важно, так как позволяет в KTV-парсер запихнуть стандартный JSON, и он его съест с удовольствием. А можно воспользоваться удобствами, типами например.
Где же тут типы? В вышеприведенном случае типы выводятся из значений. «Alex» — это строчный литерал, значит тип name'а — «string», coolness'у достался «double», а isAProgrammer — «bool». Кроме этих типов есть ещё «null» (он же «nil», привет коллегам), «int» и «color». Давайте запишем этот же пример, но полностью указывая типы:
{
name(string): Alex
coolness(double): 3.1415
isAProgrammer(bool): true
}
Никуда не делись и вложенные объекты/массивы. С дополнениями:
property(font): {name:..., size:...}
property(point): [2, 3]
Присутствуют сылки, возможность сослаться на любую другую пропертю. Как-то так:
{
property: value
another: @property
}
Это позволяет сократить запись некоторых ветвистых объектов, или просто задавать константы, обращаясь к ним в других частях файла. Первая возможность полезна в REST'е, если структура объектов нетривиальная. Вторая — в конфигурационных файлах.
Идея миксинов также позаимствована из других языков. Они позволяют проперти одного объекта (или объектов) приделать другому объекту. Можно представить себе это, как наследование, но наследование — это из ООП, там поведение наследуется, тут только свойства. Так что лучше смешивать.
{
object: { a: ..., b: ...}
object2(+object): { c: ..., d: ... }
}
В данном примере объект object2 будет после парсинга содержать как свои проперти, так и проперти из объекта object. То есть, a, b, c и d.
Я не удержался и организовал комментарии. Их можно задавать либо при помощи //, либо #. Оба типа комментариев — строчные, блочных комментариев нет.
Со вторым типом (который октоторповый) есть небольшая проблема. Дело в том, что литерал цвета предполагается задавать как-раз в стандартном CSS-виде, то есть #rrggbbaa, что конфликтует с текущим вариантом записи комментариев. Так что, возможно, в будущем останется только С-вариант (//).
Для меня этот формат, и парсер этого формата нужен в двух местах:
Поэтому я рассматриваю работу с форматом именно для Swift'а. В принципе, формат достаточно простой и не должно быть сложно организовать его парсер в любом языке.
Проблемы Swift сейчас не позволяют сделать по-настоящему правильную загрузку/сериализацию объектов из/в KTV. Поэтому процесс работы с форматом предполагается следующий:
@objc
) или структуры. Каждый класс должен реализовывать протокол KTVGenerated
.Модельная структура может выглядеть, например, так:
public struct RootObject: KTVGenerated {
var string:String // просто пропертя
var stringOrNil:String? // optional
var int:Int // числа
var stringArray:[String] // массивы
var stringDictionary:[String:Int] // ассоциативные массивы
var object:ChildObject? // ссылка на другой модельный класс
private var _privateString:String // эта пропертя не будет сериализовываться
private(set) var _privateSetString:String // эта — тоже
let _constantString:String // и константы тоже не сериализуем
}
Видно, что поддерживаются все основные фичи:
История создания такого парсера — тема для отдельной статьи. Задачи одновременного поддержания структур и классов, способы задания атрибутов без наличия самих атрибутов, использование SourceKit'а вместо рефлекшна для анализа файлов, необходимость кастомных мапперов (например, для парсинга нестандартных дат). Сам парсер сейчас в процессе активной разработки, и постоянно меняется. Но, если будет достаточный интерес — выложу рабочий проект, обсудим варианты.
https://xkcd.com/927/ [4]
JSON — так себе формат для передачи данных между приложениями. Это — формат описания объектов в JavaScript'е. А мы постоянно используем его для совершенно других целей, впихивая и по делу и без дела.
Мне кажется, пора переходить к чему-то, более приспособленному к выполняемым задачам. К новому Swift'у с его строгой типизацией, к сложным структурам данных, которые часто приходится передавать на мобильные клиенты с сервера. Нужен формат, синтаксис которого можно будет проверять в IDE, в процессе компиляции и при парсинге. И, мне кажется, что KTV, не меняя кардинально структуру, практически не усложняя уже известный формат, добавляет несколько удобных мелочей.
Скорее всего, я много чего упустил или не учёл. Может, у кого-то есть похожий опыт? Пишите в комментариях, или в почту: alex@jdnevnik.com, обсудим!
Автор: bealex
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/json/114340
Ссылки в тексте:
[1] http://www.json.org: http://www.json.org
[2] http://www.yaml.org/spec/1.2/spec.html: http://www.yaml.org/spec/1.2/spec.html
[3] Ångström Style System: http://www.lonelybytes.com/blog-ru/2014/4/15/-
[4] https://xkcd.com/927/: https://xkcd.com/927/
[5] Источник: https://habrahabr.ru/post/278763/
Нажмите здесь для печати.