GrabDuck

Создание API: в рамку и на стену

:

Каждый программист — проектировщик API. Хорошие программы состоят из модулей, а протокол взаимодействия модулей — это тоже API. Хорошие модули используются повторно.

API — это большая сила и большая ответственность. У хорошего API будут благодарные пользователи; поддержка плохого превратится в кошмар.

Публичный API — не воробей, опубликуешь — не уберешь. Есть только одна попытка сделать все правильно, поэтому постарайся.

API должно быть легко использовать, но сложно использовать неправильно. Сделать что-то простое с помощью такого API должно быть просто; сложное — возможно; сделать что-то неправильно должно быть невозможно, или, по крайней мере, трудно.

API должен описывать сам себя. Изучение кода на таком API не вызывает желания читать комментарии. Вообще, комментарии редко нужны.

Перед разработкой API собери требования с долей здорового скептицизма. Осознай общие задачи и реши их.

Оформляй требования как шаблоны использования API. Сверяйся с ними в процессе проектирования.

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

Закодируй шаблоны использования до реализации API, даже до подробного определения. Благодаря этому ты не потратишь время на принципиально нежизнеспособный API.

Изменяй код шаблонов использования по мере развития API. Это исключит неприятные сюрпризы. Потом шаблоны можно будет употребить в примерах, документации и тестах.

Код примеров должен быть образцовым. Пользователи будут копировать его в свои программы. Малейшая ошибка аукнется сторицей.

Нельзя угодить всем и во всем, стремись угодить всем одинаково. Большинство API слишком заточены под нужды своих создателей, что лишает гибкости.

Будь готов к собственным ошибкам в дизайне API. Наивно полагать, что ты продумал все до единого сценарии использования API, побочные эффекты взаимодействия с окружением и т. д.

При разработке API один в поле не воин. Покажи API как можно большему числу коллег и воспринимай критику. Они могут заметить твои ошибки.

Названия имеют значение. Стремись к ясности и симметрии. Будь последователен. Каждый API — это маленький язык, пользователи будут учиться читать и писать на нем. Код на хорошем API похож на естественный текст.

Не получается придумать хорошие названия — вернись к проектированию. Не бойся перелопачивать API. Если названия ложатся одно к одному, ты на верном пути.

Сомневаешься — удаляй. Пожалуй, главное правило разработки API. Касается всего: блоков функциональности, модулей, классов, функций, методов, параметров. Каждая отдельная часть API должна быть такой маленькой, как только возможно, но не меньше. Что-то добавить всегда успеешь, а убрать ничего нельзя. Прежде всего уменьшай количество смыслов, а не классов или методов.

Следи, чтобы детали реализации не проникли в API. Это сбивает пользователей и затрудняет развитие API. Не всегда легко понять, что есть деталь реализации: Остерегайся чрезмерной подробности. Например, не указывай в API алгоритм хеш-функции.

Сокращай изменяемость. Неизменяемые объекты просты и безопасны.

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

Держи в уме последствия решений в архитектуре API для производительности, но не ставь ее выше качества API. К счастью, хороший API обычно дружит с высокой производительностью.

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

Сокращай доступность. Сомневаешься — делай приватным. Это упрощает API и уменьшает связность.

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

Продумывай и документируй возможность наследования, или запрещай его. Опиши в документации, как и когда методы класса вызывают друг друга. Без этого безопасное наследование невозможно.

Не вынуждай пользователя делать что-либо за библиотеку. Верный признак — повторяющийся код при работе с API. Это утомляет и чревато ошибками.

Следуй принципу наименьшего удивления. Функция должна делать что-то наиболее ожидаемое от своего названия и сигнатуры.

Стремись, чтобы ошибки при использовании всплывали как можно раньше. Лучше всего — на этапе компиляции. Во время выполнения — желательно при первом же ошибочном вызове.

Предоставь программный доступ ко всему, что доступно в виде текста. Негуманно обрекать пользователей на разбор строчек. Хуже того, формат текста фактически станет частью API. Пример: если можно напечатать трассировку стека, должна быть возможность и получить список ссылок на фреймы.

Перегружай методы/функции с осторожностью. Если их действие различается, лучше дать разные названия.

Применяй самые подходящие типы. Например, принимай и передавай IP-адрес как специальный тип, а не число или строку.

Держись одного порядка аргументов в функциях. Иначе пользователи все перепутают.

Избегай длинных списков аргументов, особенно если несколько штук одного типа идут подряд.

Методы не должны возвращать значения, требующие особой обработки. Пользователи будут забывать о проверках. Например, возвращай пустой массив или список, а не null.

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

Бросай непроверяемые исключения, если пользователь вряд ли сможет осмысленно обработать ошибку.

Создание API — искусство, а не наука. Думай о красоте, доверяй интуиции. Не следуй этим правилам слепо, но нарушай их лишь изредка и по вескому поводу.



Презентация и видео: то же самое, но несколько другими словами и с примерами на Java.