Как стать автором
Обновить

Комментарии 5

Вообще удивительно, как мало внимания уделяют API в наш век микросервисов, контейнеров, веб-приложений и cloud-инфраструктуры. На западе с этим как-то более внимательно, но тоже далеко не так хорошо, как могло бы.
Если кто-то всё же хочет подтянутся по этому вопросу, наверно следует обратить внимание на книгу Непрерывное развитие API. Правильные решения в изменчивом технологическом ландшафте.

Как непривычно видеть Паскалевский стиль имён в С.

Хорошая идея, но в отрыве от остальных мер по написанию качественного кода профит оказывается катастрофично мал. Если библиотека плохо продумана, то упаковка функций в объект будет красива лишь первые несколько версий. Со временем же нагромождение API_v1, API_v2, API_v3 будет только вызывать шок из-за дублирования общих прототипов в смежных версиях API. (Либо я не понял идею).
А изнутри библиотека как была, так и осталась, со всеми современными проблемами разработки. От упаковки API в объект основная масса кода не изменится.

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

Собственно, пример относящийся к упоминаемому в статье Vulcan — OpenGL vs Direct3D. Microsoft с каждой версией делали несовместимую версию библиотеки, что позволяло своевременно избавляться от устаревших функций. OpenGL вместо этого пытался сохранить совместимость, так что API раздувалось и раздувалось — большинство функций оперируют глобальным состоянием (а те которые не оперируют есть только в последних версиях), загрузка вершин по одной через glVertex, fixed pipeline с туманом и освещением, всё это должно было поддерживаться создателями драйверов в произвольных комбинациях. Какие-то попытки с Core\Compatibility были, но итог мы все знаем, вместо OpenGL5 появился Vulcan.
В статье предлагается некий промежуточный вариант — чтобы библиотека была одна, при этом первая функция возвращала таблицу со всеми вызовами direct3d1.0, вторая — со всеми вызовами direct3d2.0, и так далее. Звучит довольно монструозно, а в чем польза вообще непонятно.

2. Усложняется написание байндингов.
Если байндинги пишет не разработчик библиотеки а тот кто собирается ее использовать, то он лишается даже минимальной проверки на соответствие имен. Достаточно пропустить одну функцию (из-за невнимательности при ручной генерации или ошибки парсинга при автоматической) и будут вызываться вообще не те функции.
Насчет автоматической генерации — если мне, скажем, надо написать байндинги для Ruby для библиотеки загрузки png, то в случае «классической» библиотеки я возьму сишный хедер, возьму документацию к Ruby Fiddle и копипастом легко напишу требуемый десяток строчек. А вот если это библиотека с предлагаемой системой API, то я даже не буду пытаться. Какие-то XML файлы содержащие описание таблицы маршрутизации, читать к ним документацию чтобы понять как написать автоматический генератор, плюс разбираться как вызывать из этой таблицы функции, за что, я просто хотел загрузить пару картинок.
Советую обратить внимание на VirtualBox XPCOM. Аналогично Mozilla, на Windows это просто системный COM. В отличие от Mozilla, двоично стабилен. Библиотек на нём особо не делают, так что и с генераторами привязок не густо, но это хоть можно изменить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий