Api и "пределы значений": соответствуют ли они?
Часто ли вы видите в документации API (например, в "javadoc публичных функций" ) описание "ограничений по стоимости", а также классическую документацию?
Примечание: Я не говорю о комментариях в коде
Под "пределами значений" я имею в виду:
- может ли параметр поддерживать нулевое значение (или пустую строку или...)?
- имеет ли значение "возвращаемое значение" значение null или гарантированно никогда не будет null (или может быть "пустым" или...)?
Пример:
Я часто вижу (без доступа к исходному коду):
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* @param aReaderNameRegexp filter in order to return only reader matching the regexp
* @return array of reader names
*/
String[] getReaderNames(final String aReaderNameRegexp);
Мне хотелось бы видеть:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* @param aReaderNameRegexp filter in order to return only reader matching the regexp
* (can be null or empty)
* @return array of reader names
* (null if Report has not yet been published,
* empty array if no reader match criteria,
* reader names array matching regexp, or all readers if regexp is null or empty)
*/
String[] getReaderNames(final String aReaderNameRegexp);
Моя точка зрения:
Когда я использую библиотеку с функцией getReaderNames(), мне часто даже не нужно читать документацию API, чтобы угадать, что она делает. Но я должен быть уверен, как его использовать.
Мое единственное беспокойство, когда я хочу использовать эту функцию: что я должен ожидать в терминах параметров и возвращаемых значений? Это все, что мне нужно знать, чтобы безопасно настроить мои параметры и безопасно проверить возвращаемое значение, но я почти никогда не вижу такую информацию в документации API...
Изменить:
Это может повлиять на использование или не на проверенные или непроверенные исключения.
Как вы думаете? лимиты значений и API, они принадлежат друг другу или нет?
Ответы
Ответ 1
Я думаю, что они могут принадлежать друг другу, но не обязательно иметь. В вашем сценарии кажется, что имеет смысл, что лимиты документированы таким образом, что они появляются в сгенерированной документации API и intellisense (если язык /IDE поддерживает ее).
Я думаю, что это зависит и от языка. Например, Ada имеет собственный тип данных, который является "ограниченным целым числом", где вы определяете целочисленную переменную и явно указываете, что она будет (и всегда) находиться в пределах определенного числового диапазона. В этом случае сам тип данных указывает на ограничение. Он все равно должен быть видимым и обнаружимым через документацию API и intellisense, но не будет тем, что разработчик должен указать в комментариях.
Однако языки, такие как Java и С#, не имеют такого типа ограниченного целого числа, поэтому разработчику пришлось бы указывать его в комментариях, если бы это была информация, которая должна стать частью публичной документации.
Ответ 2
Я думаю, что эти граничные условия наиболее определенно принадлежат API. Тем не менее, я (и часто делаю) сделаю шаг дальше и укажу, ЧТО эти нулевые значения означают. Либо я указываю, что это вызовет исключение, либо я объясню, каковы ожидаемые результаты при передаче граничного значения.
Трудно не забыть всегда делать это, но это хорошо для пользователей вашего класса. Также трудно поддерживать его, если контракт представляет собой метод изменений (например, нулевые значения изменяются так, чтобы их нельзя было допускать). Вы также должны быть внимательны и обновлять документы при изменении семантики метода.
Ответ 3
Вопрос 1
Часто ли вы видите в документации API (например, в "javadoc публичных функций" ) описание "ограничений по стоимости", а также классическую документацию?
Почти никогда.
Вопрос 2
Мое единственное беспокойство, когда я хочу использовать эту функцию: что я должен ожидать в терминах параметров и возвращаемых значений? Это все, что мне нужно знать, чтобы безопасно настроить мои параметры и безопасно проверить возвращаемое значение, но я почти никогда не вижу такую информацию в документации API...
Если я неправильно использовал функцию, я бы ожидал, что RuntimeException
, вызванный методом или RuntimeException
в другой (иногда очень далекой) части программы.
Комментарии, подобные @param aReaderNameRegexp filter in order to ... (can be null or empty)
, мне способ реализовать Дизайн по контракту в человеческом существе язык внутри Javadoc.
Использование Javadoc для принудительного исполнения проекта по контракту использовалось iContract
, теперь оно возродилось в JcontractS
, что позволяет указывать инварианты, предпосылками, постусловиями, более формализованным способом по сравнению с языком человека.
Вопрос 3
Это может повлиять на использование или нет для отмеченных или непроверенных исключений. Как вы думаете? лимиты значений и API, они принадлежат друг другу или нет?
Язык Java не имеет функции "Дизайн по контракту", поэтому у вас может возникнуть соблазн использовать Execption
, но я согласен с вами в том, что вы должны знать о Когда выбрать отмеченные и непроверенные исключения. Вероятно, вы можете использовать unchecked IllegalArgumentException
, IllegalStateException
, или вы можете использовать модульное тестирование, но основная проблема заключается в том, как сообщать другим программистам, что такой код относится к Design By Contract и должен рассматриваться как контракт, прежде чем изменять его слегка.
Ответ 4
Я думаю, что они делают, и всегда размещали комментарии в файлах заголовков (С++).
В дополнение к действительным комментариям ввода/вывода/возврата, я также отмечаю, какие исключения, вероятно, будут выбраны функцией (поскольку я часто хочу использовать возвращаемое значение для... нужного значения, я предпочитаю исключения из коды ошибок)
//File:
// Should be a path to the teexture file to load, if it is not a full path (eg "c:\example.png") it will attempt to find the file usign the paths provided by the DataSearchPath list
//Return: The pointer to a Texture instance is returned, in the event of an error, an exception is thrown. When you are finished with the texture you chould call the Free() method.
//Exceptions:
//except::FileNotFound
//except::InvalidFile
//except::InvalidParams
//except::CreationFailed
Texture *GetTexture(const std::string &File);
Ответ 5
@Fire Lancer: Верно! Я забыл об исключении, но хотел бы, чтобы они упомянули об этом, особенно исключение исключенной "runtime", которое этот публичный метод мог бы выбросить
@Майк Стоун:
вы должны быть прилежными и обновлять документы, когда вы изменяете семантику метода.
Mmmm Я очень надеюсь, что публичная документация API будет, по крайней мере, обновляться всякий раз, когда происходит изменение, которое влияет на контракт функции. Если нет, эти документы API могут вообще вообще отказаться.
Чтобы добавить еду к своим мыслям (и пойти с @Scott Dorman), я просто натыкаюсь на будущее аннотаций java7
Что это значит? То, что определенные "граничные условия", а не в документации, должны быть лучше в самом API и автоматически использоваться во время компиляции с соответствующим кодом, созданным "assert".
Таким образом, если в API API '@CheckForNull', писатель функции может уйти, даже не документируя его! И если семантическое изменение, его API будет отражать это изменение (например, "no more @CheckForNull" )
Такой подход предполагает, что документация для "граничных условий" является дополнительным бонусом, а не обязательной практикой.
Однако это не распространяется на специальные значения возвращаемого объекта функции. Для этого необходима полная документация.