Recentemente ho sviluppato la mia API e con quell'interesse investito nella progettazione dell'API sono stato fortemente interessato a come posso migliorare la mia progettazione dell'API.
Un aspetto che è emerso un paio di volte è (non dagli utenti della mia API ma nella mia osservazione osservativa sull'argomento): si dovrebbe sapere solo guardando il codice che chiama l'API quello che sta facendo .
Ad esempio, vedi questa discussione su GitHub per il repository discorso , va qualcosa del tipo:
foo.update_pinned(true, true);
Solo guardando il codice (senza conoscere i nomi dei parametri, la documentazione ecc.) Non si può indovinare cosa farà: cosa significa il secondo argomento? Il miglioramento suggerito è di avere qualcosa di simile:
foo.pin()
foo.unpin()
foo.pin_globally()
E questo chiarisce le cose (il secondo argomento era se fissare il pippo a livello globale, immagino), e sono d'accordo in questo caso che il successivo sarebbe sicuramente un miglioramento.
Tuttavia, credo che possano esserci casi in cui i metodi per impostare uno stato diverso ma logicamente correlato sarebbero meglio esposti come una chiamata di metodo piuttosto che separati, anche se non si saprebbe cosa sta facendo semplicemente guardando il codice . (Quindi dovresti ricorrere a esaminare i nomi dei parametri e la documentazione per scoprirlo - cosa che personalmente farei sempre, non importa se non avessi familiarità con un'API).
Ad esempio espongoSetVisibility(bool, string, bool)
un metodo su un FalconPeer e riconosco solo guardando la linea:
falconPeer.SetVisibility(true, "aerw3", true);
Non avresti idea di cosa stia facendo. Sta impostando 3 diversi valori che controllano la "visibilità" falconPeer
in senso logico: accetta richieste di join, solo con password e rispondi a richieste di rilevamento. Dividere questo in 3 chiamate di metodo potrebbe portare un utente dell'API a impostare un aspetto della "visibilità" dimenticando di impostare gli altri a cui li costringo a pensare esponendo l'unico metodo per impostare tutti gli aspetti della "visibilità" . Inoltre, quando l'utente vuole cambiare un aspetto, quasi sempre vorrà cambiare un altro aspetto e ora può farlo in una chiamata.
setSize(10, 20)
non è leggibile come setSize(width=10, height=20)
o random(distribution='gaussian', mean=0.5, deviation=1)
. Nelle lingue con parametri nominali forzati, i booleani possono trasmettere esattamente la stessa quantità di informazioni dell'uso di enumerazioni / costanti nominate, quindi possono essere utili nelle API.
update
metodo:foo.update(pinned=true, globally=true)
. Oppure:foo.update_pinned(true, globally=true)
. Pertanto, la risposta alla tua domanda dovrebbe tenere conto anche delle funzionalità della lingua, perché una buona API per la lingua X potrebbe non essere buona per la lingua Y e viceversa.