Pattern catena di comando / Responsabilità per la mia semplice API. Una buona idea?

2

Ho bisogno di scrivere una semplice API per un progetto su cui sto lavorando. Questa API verrà utilizzata internamente per eseguire alcune azioni sul lato server attivate dalle chiamate AJAX.

Per semplificare le cose, ho pensato di utilizzare il modello Chain of of Command / Responsibility.

Ecco ulteriori dettagli su ciò che voglio fare:

Sto creando una "dashboard" in cui gli amministratori della mia app saranno in grado di aggiornare le informazioni (metadati) sugli elementi memorizzati in un database.

Per rendere le cose facili e semplici agli amministratori, ho scelto di usare AJAX. Quindi, se un amministratore vuole eliminare un articolo, (s) fa clic sul "pulsante Elimina". Una richiesta POST viene quindi inviata alla pagina edit.php con tutte le informazioni necessarie per eseguire la cancellazione (azione: delete, element: link, id: xx ...). Dove action , element e naturalmente id possono cambiare.

Ecco perché ho optato per una mini-API che, a seconda dei dati action e element , chiama una funzione diversa da una classe diversa.

Ora, per implementare l'API, ho deciso di utilizzare il modello di progettazione Chain-of-Responsibility. Perché? Perché posso facilmente aggiungere, eliminare o aggiornare le classi senza dover modificare l'API stessa.

Il modello di progettazione Chain of Responsibility è adatto al mio caso?

    
posta ahmed 29.09.2013 - 19:00
fonte

3 risposte

4

L'idea del pattern chain-of-command è di costruire una catena di handler e passare un comando lungo questa catena finché uno dei gestori non gestisce il comando. Questo comportamento si trova in genere nell'elaborazione degli eventi, dove, per esempio, un evento click da un pulsante dell'interfaccia utente attiva la gerarchia degli elementi dell'interfaccia utente finché non raggiunge un elemento a cui è associato un rispettivo gestore. Questo gestore può quindi decidere se gestisce il comando - terminando efficacemente l'elaborazione dell'evento - o meno - nel qual caso l'evento viene propagato ulteriormente lungo la catena.

Supponiamo ora di utilizzare tale modello per la tua web API. Quello che descrivi suona come una classica interfaccia CRUD (L) per me, dove le tue azioni sono (un sottoinsieme di) creare, leggere, aggiornare ed eliminare. Dici di avere richieste di cancellazione e presumo che tu voglia anche qualche tipo di richiesta di aggiornamento. Supponiamo inoltre di aver scritto i rispettivi gestori hupd e hdel per queste richieste di tipi. Seguendo il modello chain-of-command, puoi creare la catena [hupd, hdel] per gestire le richieste alla tua API. Quello che succede è che ogni richiesta di aggiornamento passata nella catena viene immediatamente gestita da hupd , mentre ogni richiesta di eliminazione viene respinta da hupd e passata a hdel , che lo gestisce. Questo comportamento mostra una mappatura fissa tra azioni e gestori che rende effettivamente inutile la catena. (In effetti, la catena riduce anche le prestazioni del sistema, a causa del controllo e del passaggio di ogni richiesta di cancellazione). Perché succede? Perché non esistono due gestori responsabili di diversi sottoinsiemi di richieste con lo stesso tipo di azione. Quello che vuoi veramente avere qui è una mappatura diretta ["update" = > hupd, "delete" = > hdel] e un dispatcher che accetta le rispettive richieste e le passa direttamente al rispettivo gestore. Un tale progetto può ancora essere esteso per quanto riguarda le nuove azioni, se esiste un registro dinamico con la mappatura.

Ora potresti dire che vuoi avere gestori diversi per, per esempio, la cancellazione di elementi di tipo A e B. Che cosa ti dà gestori per sottoinsiemi di richieste con lo stesso tipo di azione. Ma ancora una volta, si ha una mappatura diretta e fissa tra i gestori e il tipo di elemento, cioè, è possibile inviare ripetutamente richieste in base al tipo di elemento di destinazione. Questo ti dà un dispatch a due livelli, dove con una chain-of-command potresti passare la richiesta attraverso il numero di azioni volte al numero di gestori di tipi di elementi, nel peggiore dei casi.

Conclusione: non raccomanderei il modello chain-of-command per implementare questo tipo di API. Affinché il pattern abbia un valore, è necessario uno scenario in cui si desidera aggiungere e rimuovere dinamicamente i gestori e in cui la condizione di quando un gestore gestisce effettivamente un evento non è esprimibile da una semplice mappatura da costanti.

    
risposta data 03.10.2013 - 12:05
fonte
2

Non è consigliabile utilizzare un unico metodo per gestire tutte le operazioni di richiesta. Idealmente dovresti usare DELETE per gestire le operazioni di cancellazione, aiutandoti così ad avere un'API che dice esattamente che cos'è l'API e POST, GET e così via.

Ti suggerisco di iniziare a definire prima le API come punto di partenza.

  1. Eliminazione di un elemento nella dashboard - > link - Elimina operazione
  2. Aggiornamento di un elemento - > link - Ottieni operazione

Vedi, l'API è auto-esplicativa e darebbe un'immagine chiara di ciò che vuoi fare e ti aiuterà nella manutenzione.

Nel controller è possibile rilevare l'operazione e quindi chiamare i rispettivi servizi per ogni operazione per eseguire un'azione. COR potrebbe non essere una buona opzione, in quanto non si adatta qui.

    
risposta data 08.10.2013 - 07:25
fonte
0

Prima di tutto, nota che la domanda è errata, perché il pattern chain of command non è correlato all'API pubblica, ma alla sua implementazione interna, lato server.

Detto questo, il modello catena di comando si adatta bene alle tue esigenze. Poiché l'API viene estesa con nuove azioni e / o elementi, è possibile aggiungere nuovi gestori alla catena per implementare nuovi comportamenti, senza modificare quelli esistenti.

    
risposta data 03.10.2013 - 09:52
fonte

Leggi altre domande sui tag