Verifica se esiste una responsabilità di un chiamante o di un'API?

4

È meglio per un'API quando fornisce metodi aggiuntivi che controllano se qualcosa esiste prima di aggiungere?

Ad esempio:

if (!userManager.HasPermission(user, "somePermission")
   userManager.AddPermission(user, "somePermission");

vs

userManager.AddPermisionIfDoesntExist(user, "somePermission");

Se utilizzi questo HasPermission in molti posti, non sarebbe meglio creare un metodo come AddPermisionIfDoesntExist ?

Oppure, se i duplicati non sono consentiti, dovrebbe invece AddPermission controllarlo?

Quindi sarebbe simile al modo in cui Dictionary è progettato, con metodi come TryAddPermission e AddPermission che generano eccezioni quando il permesso esiste già?

Inoltre, nota che AddPermission e HasPermission stanno effettuando chiamate al database

    
posta Konrad 06.12.2018 - 15:25
fonte

3 risposte

6

La risposta corretta qui dipende in larga misura dal fatto che la risorsa da modificare sia condivisa.

if (Files.exists(path)) {
    Files.delete(path);
} catch (NoSuchFileException x) {
    System.out.println("Er wait, how'd we get here?");
}

Qui ci troviamo di fronte al fatto che non siamo l'unico processo con accesso a questa risorsa. Se ce l'avessimo, potremmo evitare la brutta eccezione di NoSuchFileException .

Quindi cosa fare? Bene, possiamo bloccare la risorsa per ottenere una combinazione "test and set" atomica in modo che possiamo controllare cosa sta succedendo o possiamo semplicemente fare in modo che l'API faccia tutto questo.

Files.deleteIfExists(path);

Qui la conoscenza dell'esistenza della risorsa viene restituita e ignorata poiché non ci interessa.

Tuttavia, se sappiamo in anticipo che non ci interessa, allora

userManager.AddPermision(user, "somePermission");

non ha motivo di buttare quando il permesso esiste già. Ha solo un brutto nome. In questo caso preferirei vedere questo:

userManager.SetPermision(user, "somePermission");

Dopo di che mi sentirò bene supponendo che qualunque altra cosa stia succedendo, ora è impostata.

    
risposta data 06.12.2018 - 18:03
fonte
1

Di solito è meglio se l'API è scritta in modo che il controllo stesso sia interno, ma dipende da quale comportamento si desidera sia dall'API che dal chiamante.

  • Nascosto tutto dietro l'API in cui il chiamante non dovrebbe preoccuparsi e la sua più di una cosa di implementazione interna L'autorizzazione non ha altre proprietà: addPermission(user, 'somePermission')
    E stiamo bene se questa chiamata crea solo la voce di permesso (una sorta di schema di amministrazione flessibile)

  • lanciare un'eccezione se il chiamante deve aver prima fatto qualcos'altro (ad esempio, impostare le autorizzazioni che non dovrebbero essere sotto controllo del programma)
    L'autorizzazione non può essere aggiunta dinamicamente try {addPermission(user, 'somePermission') } catch e(){alert ("permission doesn't exist")}

  • Fornire un metodo di sostituzione se si desidera che il chiamante richieda facoltativamente all'API di eseguire il lavoro per proprio conto (e presumendo che ciò sia pratico per l'API da eseguire per loro)
    addPermission(user, 'somePermission', addIfMissing=true)
    Ancora una volta, dobbiamo essere ok se questa chiamata crea solo la voce di autorizzazione

  • Se sono richieste proprietà aggiuntive per il precursore, esporre metodi aggiuntivi per il chiamante per creare la cosa.
    Se non si espone un controllo di esistenza, il chiamante dovrebbe implementare un tentativo / aggirare la chiamata del metodo principale nel caso in cui sia necessario effettuare la chiamata del precursore. È meglio esporre anche il controllo dell'esistenza in modo che possano renderlo evidente nel loro codice:

if(!permissionExists("somePermission")
{createPermission("somePermisson",newPermissionName)}
addUserPermission(user,"somePermission")

    
risposta data 06.12.2018 - 16:04
fonte
0

Supporta entrambi i flussi di lavoro.

Alcuni chiamanti vorranno usare HasPermission() per convalidare le ipotesi prima di continuare con una transazione lunga o costosa - o per convalidare altrimenti assunzioni o debug. Questo metodo dovrebbe essere più accessibile di AddPermission() per supportare tali flussi di lavoro.

Tuttavia, se un cliente sceglie di chiamare AddPermission() senza prima verificare l'esistenza, non obbliga a catturare eccezioni o a distinguere tra tipi di successo . E a tal fine, restituire un oggetto risposta in grado di comunicare le modalità sfumate di successo e fallimento. Qualcosa come:

{
  success: true|false,
  status: Added|AlreadyExists|CannotAdd|NoPermissions|etc..,
  message: "Description/Guidance regarding the status code."
}
    
risposta data 06.12.2018 - 18:11
fonte

Leggi altre domande sui tag