Esistono alcune soluzioni che consentono di eseguire transazioni secondarie sul modello di business?

2

La mia domanda è nell'intestazione. Vorrei sapere se esiste una soluzione architettonica che consente di eseguire transazioni nidificate sul modello di business. Lasciatemi spiegare: il flusso standard per il servizio web è

  • convalida i dati di input
  • richiesta di processo
  • risultati persistenti
  • scrivi risposta

Tuttavia, ci sono casi in cui non è possibile convalidare i dati prima che la richiesta venga elaborata, ovvero devo convalidare il sistema dopo l'esecuzione della richiesta: consente di chiamare questo caso inverted validation case . Se il sistema non è più valido, vorrei ripristinare le modifiche nel modello di business allo stato iniziale. Dovrei notare che il sistema dovrebbe avere buone prestazioni. L'elaborazione della richiesta consuma una grande quantità di potenza di calcolo, quindi è impossibile eseguire le modifiche due volte, una volta per la convalida e una volta per l'elaborazione della richiesta effettiva. Al momento sto utilizzando la memorizzazione temporanea per i risultati dell'elaborazione delle richieste, quindi eseguo la convalida se passa - applico i dati dall'archiviazione temporanea al modello aziendale. Tuttavia, questa soluzione funziona alla grande se ho una transazione, ovvero devo eseguire inverted validation una sola volta, ma c'è un'altra inverted validation , che diventa codice spaghetti.

Ecco un esempio: Diciamo che abbiamo un servizio logistico che ottiene come lista di input di carichi con quantità e uscite - elenco di magazzini per ogni carico in cui è possibile conservare il carico. Ogni magazzino può immagazzinare solo una parte del carico, un altro magazzino immagazzinerà il resto. Ad esempio magazzino A magazzino 10% del carico, magazzino B negozio 50% e magazzino C 40% del carico. Per calcolare l'elenco dei magazzini, il server deve eseguire calcoli pesanti. La richiesta deve essere respinta se il carico non può essere immagazzinato in meno di 10 magazzini. Inoltre, è possibile che alcuni fornitori di merci non abbiano abbastanza fondi, quindi questo fornitore dovrebbe essere rifiutato. NOTA il sistema dovrebbe considerare che la capacità del magazzino può essere modificata da carichi già elaborati dalla richiesta corrente. Quindi qui abbiamo due transazioni: una grande transazione per l'intera richiesta e due annidate per il caso in cui non ci sono magazzini e quando non ci sono fondi, come puoi vedere non è possibile applicare subito le modifiche al modello di business. NOTA : il problema nell'esempio è un problema con il giocattolo: l'ho creato solo per mostrare il problema reale.

    
posta Oleksandr Papchenko 06.12.2018 - 09:02
fonte

1 risposta

2

Come vedo, hai un paradigma che funziona quando la richiesta segue la sequenza di operazioni prevista, vale a dire: convalida richiesta, richiesta di processo, risultati permanenti, risposta in scrittura. Presumibilmente ciascuna richiesta ha la sua implementazione individuale per ciascuno di questi passaggi, ma i passaggi rimangono costanti.

Ora ti viene data una situazione in cui i passaggi possono cambiare. Ci sono diversi approcci per questo. Uno richiederebbe meno refactoring, ma alla fine è meno flessibile delle due soluzioni. L'altro dovrebbe potenzialmente affrontare eventuali nuovi tipi di problemi di questo tipo in futuro. Permettimi di inserirli entrambi e ti permetterò di scegliere quale preferisci:

Avvicinamento agli eventi

In questo momento hai una classe che chiama queste quattro operazioni. Se alla fine decidi che questa sequenza di operazioni debba ancora essere rispettata per la maggior parte, significa che l'elaborazione che deve essere eseguita prima della convalida potrebbe essere considerata "parte della convalida". Tuttavia, la tua convalida corrente, se credo che sia corretta, è probabilmente costruita solo per gestire l'input della richiesta.

Per risolvere questo problema, puoi semplicemente aggiungere hook di eventi che inizialmente quando aggiunti alla tua classe non fanno nulla. Esempi di questi hook potrebbero essere:

onPreValidation, onPostValidation, onPreProcess, onPostProcess, etc.

La tua classe chiamerebbe ognuno nel loro rispettivo ordine e passerà tutte le informazioni restituite nella pre fase alla gestione effettiva di quella fase. Dovresti quindi creare stub di questi metodi che non fanno nulla, e quindi per la maggior parte delle richieste, nulla cambierebbe.

Tuttavia questo ti consente di ignorare questa classe ed eseguire azioni speciali prima o dopo ciascuna fase. Ciò richiederebbe la minima quantità di refactoring, ed è fedele all'idea "a quattro fasi" della tua richiesta. Se è necessario, puoi anche creare una fase personalizzata per richieste particolari che non si discostano troppo da questo.

Tuttavia non dovresti adottare questo approccio se ritieni che ciò che devi ottenere sia troppo diverso dall'idea di "quattro fasi". Una richiesta radicalmente nuova dovrebbe essere gestita radicalmente diversa, il che mi porta al secondo approccio.

Tipo di gestore richieste astratte

Questo prende il concetto della tua classe a quattro fasi e lo riassume. Idealmente, dovrebbe essere in grado di prendere l'input della richiesta e restituire un'istanza di risposta. Quindi potenzialmente questo potrebbe essere implementato in diversi modi.

La tua classe corrente deriva quindi da questo gestore di richieste astratto e, quando viene richiamata, esegue le tipiche quattro fasi che esegue sempre normalmente, restituendo l'istanza di risposta potenzialmente serializzata e restituita al chiamante.

Usando questo tipo, crei un nuovo tipo di richiesta per il tuo nuovo caso di convalida invertito. Questo nuovo gestore di richieste esegue qualsiasi elaborazione necessaria prima della convalida. Se fatto correttamente, l'effettiva implementazione di queste fasi dovrebbe essere fatta altrove, quindi probabilmente useresti una fabbrica astratta per creare classi concrete per gestire queste singole fasi. Questa fabbrica astratta verrebbe probabilmente fornita dal gestore di richieste astratto stesso. Quindi, idealmente, tutto ciò che viene modificato sono i passaggi e l'ordine di questi passaggi nel contesto del gestore della richiesta.

Anche se ciò richiederebbe il più refactoring, in futuro creerà una buona base per nuovi tipi di richieste.

Conclusione

Permettetemi di sottolineare che in entrambe le soluzioni stiamo astrarre i passaggi della richiesta e non l'effettiva implementazione. Ciò dovrebbe creare una buona base per lo sviluppo futuro e assicurare che sia possibile accogliere nuove richieste in futuro.

    
risposta data 06.12.2018 - 12:17
fonte