Kürzlich habe ich meine eigene API entwickelt und mit dem investierten Interesse an API-Design war ich sehr interessiert, wie ich mein API-Design verbessern kann.
Ein Aspekt, der einige Male auftauchte, ist (nicht von Benutzern meiner API, sondern in meiner beobachtenden Diskussion zum Thema): Man sollte nur anhand des Codes, der die API aufruft, wissen, was sie tut .
Sehen Sie sich zum Beispiel diese Diskussion auf GitHub für das Diskurs- Repo an. Es geht ungefähr so:
foo.update_pinned(true, true);
Wenn man sich nur den Code ansieht (ohne die Parameternamen, die Dokumentation usw. zu kennen), kann man nicht erraten, was er tun wird - was bedeutet das zweite Argument? Die vorgeschlagene Verbesserung ist, etwas zu haben wie:
foo.pin()
foo.unpin()
foo.pin_globally()
Und das klärt die Dinge auf (das zweite Argument war wohl, ob man foo global pinnen sollte), und ich stimme in diesem Fall zu, dass das letztere sicherlich eine Verbesserung wäre.
Ich glaube jedoch, dass es Fälle geben kann, in denen Methoden zum Festlegen eines anderen, aber logisch zusammenhängenden Zustands besser als ein Methodenaufruf als als separate dargestellt werden, obwohl Sie nicht wissen, was sie tun , wenn Sie sich nur den Code ansehen . (Sie müssten sich also die Parameternamen und die Dokumentation ansehen, um herauszufinden, was ich persönlich immer tun würde, egal, wenn ich mit einer API nicht vertraut bin.)
Zum Beispiel stelle ich eine Methode SetVisibility(bool, string, bool)
auf einem FalconPeer zur Verfügung und bestätige, dass ich nur die Zeile betrachte:
falconPeer.SetVisibility(true, "aerw3", true);
Sie hätten keine Ahnung, was es tut. Es werden 3 verschiedene Werte festgelegt, die die "Sichtbarkeit" von falconPeer
im logischen Sinne steuern : Join-Anforderungen akzeptieren, nur mit Kennwort und Antworten auf Discovery-Anforderungen. Das Aufteilen in 3 Methodenaufrufe könnte dazu führen, dass ein Benutzer der API einen Aspekt der "Sichtbarkeit" festlegt und vergisst, andere festzulegen, über die er nachdenken muss, indem nur die eine Methode verfügbar gemacht wird, mit der alle Aspekte der "Sichtbarkeit" festgelegt werden . Wenn der Benutzer einen Aspekt ändern möchte, möchte er außerdem fast immer einen anderen Aspekt ändern und kann dies jetzt in einem Aufruf tun.
setSize(10, 20)
ist nicht so lesbar wie setSize(width=10, height=20)
oder random(distribution='gaussian', mean=0.5, deviation=1)
. In Sprachen mit erzwungenen benannten Parametern können Boolesche Werte genau so viele Informationen übermitteln wie Enums / benannte Konstanten, sodass sie in APIs nützlich sein können .
update
Verfahren:foo.update(pinned=true, globally=true)
. Oder:foo.update_pinned(true, globally=true)
. Die Antwort auf Ihre Frage sollte daher auch die Sprachfunktionen berücksichtigen, da eine gute API für Sprache X möglicherweise nicht für Sprache Y und umgekehrt geeignet ist.