Récemment, j'ai développé ma propre API et avec cet intérêt investi dans la conception d'API, je me suis vivement intéressé à la façon d'améliorer ma conception d'API.
Un aspect qui a été soulevé à plusieurs reprises est (non pas par les utilisateurs de mon API mais dans ma discussion d'observation sur le sujet): il faut savoir simplement en regardant le code appelant l'API ce qu'il fait .
Par exemple, voyez cette discussion sur GitHub pour le dépôt de discours , ça va quelque chose comme:
foo.update_pinned(true, true);
En regardant simplement le code (sans connaître les noms des paramètres, la documentation, etc.), on ne peut pas deviner ce qu'il va faire - que signifie le deuxième argument? L'amélioration suggérée est d'avoir quelque chose comme:
foo.pin()
foo.unpin()
foo.pin_globally()
Et cela clarifie les choses (le deuxième argument était de savoir s'il fallait épingler foo globalement, je suppose), et je suis d'accord dans ce cas, la dernière serait certainement une amélioration.
Cependant, je pense qu'il peut y avoir des cas où des méthodes pour définir un état différent mais logiquement lié seraient mieux exposées en tant qu'appel de méthode plutôt qu'en tant qu'appels séparés, même si vous ne savez pas ce qu'il fait simplement en regardant le code . (Il faudrait donc recourir à la recherche des noms de paramètres et de la documentation pour le savoir - ce que personnellement je ferais toujours, peu importe si je ne suis pas familier avec une API).
Par exemple, j'expose une méthode SetVisibility(bool, string, bool)
sur un FalconPeer et je reconnais simplement en regardant la ligne:
falconPeer.SetVisibility(true, "aerw3", true);
Vous n'auriez aucune idée de ce qu'il fait. Il définit 3 valeurs différentes qui contrôlent la "visibilité" du falconPeer
dans le sens logique: accepter les demandes de jointure, uniquement avec mot de passe et répondre aux demandes de découverte. Diviser cela en 3 appels de méthode pourrait conduire un utilisateur de l'API à définir un aspect de la "visibilité" en oubliant d'en définir d'autres auxquels je les oblige à réfléchir en exposant uniquement la seule méthode pour définir tous les aspects de la "visibilité" . De plus, lorsque l'utilisateur veut changer un aspect, il voudra presque toujours changer un autre aspect et peut maintenant le faire en un seul appel.
setSize(10, 20)
n'est pas aussi lisible que setSize(width=10, height=20)
ou random(distribution='gaussian', mean=0.5, deviation=1)
. Dans les langues avec des paramètres nommés imposés, les booléens peuvent transmettre exactement la même quantité d'informations que l'utilisation d'énumérations / constantes nommées, de sorte qu'ils peuvent être bons dans les API.
update
méthode:foo.update(pinned=true, globally=true)
. Ou:foo.update_pinned(true, globally=true)
. Ainsi, la réponse à votre question doit également prendre en compte les fonctionnalités du langage, car une bonne API pour la langue X peut ne pas être bonne pour la langue Y et vice versa.