При определении доступного для клиентов API, какая отраслевая практика является предпочтительной из следующих:

а) Определение набора явных методов API, каждый из которых имеет очень узкую и конкретную цель, например:

SetUserName    <name>
SetUserAge     <age>
SetUserAddress <address>

б) определение набора более общих методов API на основе параметров, например:

SetUserAttribute <attribute>

enum attribute {
    name,
    age,
    address
}

<Сильное> Мое мнение:

В пользу (а)

Для методов на основе логических значений (например, EnableFoo) я определенно предпочел бы вариант (a), поскольку намерения намного более ясны, с меньшей вероятностью потребуются расширения в будущем и это делает код более читаемым.

Например, метод с именем EnableDisableFoo, который принимает логический параметр, указывающий, следует ли включать или отключать, будет не очень ясным и не будет иметь единой цели.

Проблема усложняется там, где есть несколько вариантов.

В пользу пункта (б)

Вариант (b) - отличный способ обеспечить расширяемость API, но за счет удобства использования. С опцией (а) само имя метода API дает достаточно информации, чтобы указать, что он делает. С опцией (b) пользователь должен найти как имя метода, так и соответствующее перечисление / параметр для использования. Теоретически это ухудшает вариант (b) с точки зрения удобства использования, но, возможно, наличие меньшего количества методов - это хорошо, так что даже это не совсем так.

Другие мысли

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

Есть ли у кого-нибудь мысли по этому поводу?

3
LeopardSkinPillBoxHat 28 Янв 2009 в 08:28

3 ответа

Лучший ответ

Я лично отстаиваю (а), поскольку наша цель - сделать «статический» код максимально точным и надежным.

Используя обобщенную форму, мы вводим риск ошибок во время выполнения. Например, я мог бы установить атрибут типа age со значением, которое на самом деле является строкой и т. Д.

Это очень похоже на аргумент для определения и использования перечислений или явных типов вместо использования и возврата целых чисел в старом стиле C, поскольку вы получаете еще один уровень уверенности.

Хотя я согласен с тем, что (b) допускает расширяемость, я не встречал слишком много API-интерфейсов, которые требовали бы такой расширяемости для совершенно разных типов атрибутов. Единственное распространенное использование (b) - в полиморфном коде, где функция может технически принимать что угодно, включая расширения.

2
Uri 28 Янв 2009 в 08:42

Еще одно соображение - нужно ли устанавливать все атрибуты одновременно. Например, если вы хотите отправить что-то на принтер, вам может потребоваться установить десятки параметров (альбомная или книжная ориентация; количество копий; размер страницы; разрешение и т. Д.). Вместо определения API, который нужно вызывать десятки раз, вы можете определить одну функцию, которая принимает struct в качестве параметра, где struct содержит десятки полей и где вызывающий инициализирует struct на досуге, а затем передает struct в API за один вызов функции.

1
ChrisW 28 Янв 2009 в 08:47

Я думаю, это зависит от кода, который вы пишете. Если вы пишете о вещах, которые всегда сочетаются друг с другом (т. Е. Если вы собираетесь использовать / изменять возраст всегда с именем), тогда выбирайте b, иначе a подойдет.

Но не пытайтесь переусердствовать с (а), потому что тогда вы просто напишете намного больше строк и сделаете гораздо меньше. Хорошая идея, если вам платят за количество написанного кода :)

0
Cyril Gupta 28 Янв 2009 в 09:45