Linee guida per il posizionamento dei metodi API?

4

Esistono linee guida per l'inserimento di metodi in API quando il posizionamento non è evidente?

Esempio: ho classi A e B e un metodo X . Il lavoro svolto può essere formulato in due modi:

  1. A does X with B
  2. B does X to A

Dati i due modi di formulare questo concetto, non è chiaro se X appartiene a A o B . Esistono linee guida per l'inserimento del metodo in questo scenario?

Per un esempio più concreto, considera un utente ( A ), un evento ( B ) e un'azione di registrazione ( X ). Un utente può iscriversi a un evento ( A does X with B ) oppure un evento può aggiungere un utente all'elenco di registrazione ( B does X to A ).

    
posta Andy Hunt 04.03.2012 - 17:23
fonte

3 risposte

5

Are there any guidelines for placing methods in API when the placement isn't obvious?

In questo caso, suggerirei una "linea guida" per riprogettare l'API in modo che il posizionamento diventi ovvio .

  • Pensa agli utenti della tua API: se non è ovvio per te, il progettista, sarà probabilmente oscuro per gli utenti API che non hanno il lusso di leggere la tua mente.

    "Public APIs, like diamonds, are forever. You have one chance to get it right so give it your best..." (Joshua Bloch, How to Design a Good API and Why it Matters)

  •   

Per il tuo esempio con utente che può iscriversi a un evento e un evento che può aggiungere un utente alla lista di registrazione , darei una seria considerazione per stabilire una terza classe come SignupAction .

Per me, lo scopo principale di questa "terza" classe è di risolvere l'ambiguità in modo che gli sviluppatori che utilizzano la tua API non abbiano bisogno di rompere la testa dove cercarlo (negli utenti? negli eventi?). Questo è il punto di partenza, da cui è possibile procedere laddove i requisiti ti guidano, aggiungendo metodi, stati, classi aggiuntive ecc.

    
risposta data 04.03.2012 - 17:45
fonte
4

L'approccio a tre classi è allettante perché rispecchia la corretta progettazione del database, mappando una classe in una tabella. È molto elegante da un progetto concettuale di alto livello, ma di solito è eccessivamente complesso in un'implementazione reale, e quindi raramente utilizzato nelle API più diffuse. Di solito le relazioni sono descritte da entrambi degli oggetti coinvolti, come nel evento e utente API.

Ad esempio, guarda i toolkit della GUI con i contenitori pieni di widget. Chiama container.add(widget) , che internamente chiama qualcosa come widget.setContainer(container) . Una volta stabilita la relazione tra widget del contenitore, a volte puoi chiamare container.getWidgets() e a volte puoi chiamare widget.getContainer() .

Ora considera come sarebbe implementato con un terzo oggetto ContainerWidget . Ogni volta che volevi creare un'associazione, sarebbe come questa:

containerWidget = new ContainerWidget(container, widget);
container.addContainerWidget(containerWidget);
widget.setContainerWidget(containerWidget);

Per ottenere il contenitore di un widget dovrebbe assomigliare a questo:

widget.getContainerWidget().getContainer();

Alla fine qualcuno si arrabbia con la digitazione, e crea solo un widget.getContainer() .

Ottenere tutti i widget per un contenitore è ancora più complicato:

containerWidgets = container.getContainerWidgets();
for (containerWidget in containerWidgets)
    widgets.append(containerWidget.getWidget());

Alla fine qualcuno si arrabbierà e creerà un container.getWidgets() . Poi alla fine qualcuno noterà che, poiché abbiamo già quei metodi comunque, e piuttosto che ricostruire l'elenco ogni volta che viene chiamato, sarebbe molto più semplice solo memorizzare un elenco di widget nel contenitore e un puntatore al contenitore nel widget .

Vedi dove sto andando con questo? O si finisce con una complessità inutile, o alla fine si semplifica fino alla soluzione a due classi.

L'eccezione alla regola è quando è necessario descrivere gli attributi della relazione stessa. Ad esempio, una relazione sponsale tra due persone non merita una terza classe. Hai appena inserito un puntatore Person nella classe Person in modo che punti al coniuge corrente. Tuttavia, una relazione matrimoniale merita una terza classe, perché i matrimoni hanno luoghi, date di inizio, date di fine, ecc. Che descrivono aspetti della relazione diversi dal semplice fatto che esiste.

    
risposta data 04.03.2012 - 22:31
fonte
0

Per iniziare, un'API non dovrebbe essere raggruppata per tipo di classe.

Se stai creando un controller / gestore per organizzare eventi, dovresti disporre di un controller / gestore OrganizeEvents che esponga i metodi come ListAllEvents (), AddPersonToEven () ecc.

In generale, dovresti raggruppare le funzioni API per tema e scopo, anziché per classi. Quindi, puoi utilizzare le classi necessarie per fornire l'output corretto ogni volta.

La definizione delle relazioni sul back-end non dovrebbe essere troppo difficile e normalmente implicherebbe la riflessione su un modello di database con una tabella di collegamento.

    
risposta data 04.03.2012 - 17:52
fonte

Leggi altre domande sui tag