FSM sarà una buona soluzione?

-1

Al lavoro, stiamo creando un'app per Android. Abbiamo un modulo di business logic per parlare con un'API per le operazioni CRUD. L'app su cui sto lavorando, il modulo UI, parla al modulo di business logic per creare, aggiornare, eliminare e ottenere entità. Queste entità possono trovarsi in diversi stati (non avviati, in attesa, avviati, terminati come pochi altri). Il problema è che alcune di queste entità provengono da fonti diverse, alcune delle fonti sono prive di stato (e quindi è necessario gestirne manualmente lo stato) e alcune sono piene (per queste ci si fida dello stato delle fonti). Il modulo di business logic deve consolidare le fonti in un modello unificato per il modulo UI (poiché non vogliamo che il modulo UI sia interessato ai dettagli nitidi delle fonti di entità).

Sto lavorando al componente dell'interfaccia utente e c'è stata una discussione con gli sviluppatori che hanno lavorato al modulo di business logic su come lo stato dovrebbe essere gestito. Stavamo parlando di se il livello dell'interfaccia utente dovesse gestire lo stato degli oggetti del dominio o se il modulo della business logic dovesse gestirlo. Ho sostenuto che il modulo di business logic dovrebbe mantenere un FSM per ogni entità, in modo tale che il livello di interfaccia utente possa impartire un comando al livello di business logic per una data entità, e tale comando verrà eseguito se è valido per lo stato attuale delle entità. Se il comando era valido, l'FSM passerebbe a un nuovo stato, eseguendo effetti collaterali come le chiamate API se necessario.

Essendo l'idea generale, il livello dell'interfaccia utente non dovrebbe essere in grado di mettere gli enti aziendali in stati non validi, questo sarebbe applicato da un FSM sottostante e gli effetti collaterali potrebbero essere mantenuti in un unico posto: la tabella di transizione dello stato. Ciò ha anche il vantaggio di poter riutilizzare il modello di business logic per moduli UI completamente diversi (con UX / flussi completamente diversi) e garantire che la logica aziendale si comporti come previsto su più applicazioni client.

Questo suggerimento non ha funzionato, e invece siamo atterrati su una soluzione proposta che prevede in parte la gestione di ogni stato di entità nel livello dell'interfaccia utente e parzialmente nel livello della logica di business, che mi riguarda. Ad esempio, il livello dell'interfaccia utente interrogherà il livello della logica aziendale per le entità e potrebbe essere necessario decidere lo stato iniziale di un'entità, a seconda dello stato corrente delle entità. Ma lo strato UI dovrebbe farlo solo se lo stato attuale delle entità è x o y, non a, b o c. Oltre a ciò, l'idea reale di utilizzare un FSM per gestire lo stato sembrava essere un no-flyer (forse non mi sono spiegato abbastanza bene in quanto l'incontro è stato chiamato a breve termine).

Da quanto ho detto qui, un FSM sembra una soluzione ragionevole, e sono sulla strada giusta nel pensare che dividere la gestione dello stato attraverso la logica di business e i livelli dell'interfaccia utente sia una cattiva idea?

Sono consapevole che la domanda è piuttosto vaga, ma non sono autorizzato a discutere le specifiche del progetto al di fuori dell'azienda. Potrei creare un esempio forzato che rifletta le entità, gli stati e le transizioni del dominio se fosse di aiuto.

EDIT:

To clarify; the UI layer will maintain it's own FSM to manage it's state (i.e. the user tapped a button, issue a command to the UI FSM, if there is a valid transition, then execute side effects and transition to new state). The UI FSM may issue commands to entity FSM's as side effects of the transitions.

    
posta Thomas Cook 13.12.2018 - 19:21
fonte

1 risposta

5

La divisione della gestione dello stato tra la logica aziendale e i livelli dell'interfaccia utente è una cattiva idea.

Continui a lavorare su Finite State Machine (FSM) in un modo abbastanza scoraggiante. Penso di sapere cosa intendi davvero ma sembri uno di quegli scherzi che spegne il loro cervello e canta il gergo del modello. Devi essere chiaro su cosa intendi veramente con questo.

La ragione per cui la "gestione dello stato" è divisa tra gli strati è una cattiva idea perché hai bisogno di un'unica fonte di verità. Hai davvero bisogno di rendere quest'idea chiara anche perché è un'idea difficile. L'interfaccia utente non dovrebbe essere dove viene mantenuto lo stato del tuo modello del mondo. Dovrebbe essere solo un riflesso di ciò che l'utente vuole e conosce. Niente di più. Il mondo potrebbe essere cambiato da quando l'UI lo ha visto per l'ultima volta. Non ci dovrebbero essere decisioni prese nel codice UI. "State" nell'interfaccia utente, se insisti a chiamarlo così, non dovrebbe mai essere più di "questo è ciò che l'utente ha selezionato".

Fatto in questo modo l'interfaccia utente è stupida. È un bel posto dove guardare e cliccare le cose. Nulla qui ha nemmeno bisogno di prove scritte contro di esso perché è solo noioso codice strutturale ovvio. Nulla di interessante è permesso.

Ciò significa che la logica che avresti inserito nell'interfaccia utente deve spostarsi da un'altra parte. Mantengo almeno uno strato tra l'interfaccia utente e il modello. Quel livello, che le persone danno tonnellate di nomi diversi, può assorbire quella logica senzatetto.

Questa idea ha persino un modello chiamato dopo che si chiama l'umile oggetto . È incentrato sull'idea che gli oggetti vicini ai confini (come l'interfaccia utente) sono intrinsecamente difficili da testare. Quindi, piuttosto che ucciderci cercando di testare l'impossibile, spostiamo la logica sospettosamente interessante in un oggetto testabile che non tocchi il confine. Essere facili da testare è bello ma non è la giustificazione principale per questa mossa.

Spostando la logica in un oggetto isolato sei libero di definire un'interfaccia / API per parlare con esso che ha senso nel tuo dominio. Qualcosa di semplice, leggibile e privo di dettagli come capire cos'è una casella di testo. Tanto che puoi ottenere il tuo linguaggio onnipresente in DDD e scrivere regole aziendali che un esperto di dominio, che non ha mai scritto codice prima, potrebbe effettivamente leggere e dirti se hai sbagliato.

Quel po 'di logica aziendale è il guardiano del modello / entità. Garantisce che ciò che stiamo facendo a loro segue le regole.

This suggestion didn't fly, and instead we've landed on a proposed solution which involves partially managing each entities state in the UI layer and partially in the business logic layer, which concerns me. For instance, the UI layer will query the business logic layer for entities and may possibly need to decide the initial state for an entity, depending on that entities current state. But the UI layer should only do this if the entities current state is x or y, not a, b or c. On top of that, the actual idea of using an FSM to manage the state at all seemed to be a no-flyer (perhaps I didn't explain myself well enough as the meeting was called at short notice).

La cosa migliore da fare quando teso un'imboscata è dire "ti risponderò". Non essere d'accordo a nulla. Non presentare nulla. Non lasciarli scappare con niente.

Questa è una cosa importante e la tua voce viene irrigidita dall'incontro con l'ingegneria. Crea la tua base di supporto con conversazioni individuali e poi chiama la tua riunione. È brutto e politico ma è il mondo in cui viviamo.

Il tuo post parla di alcune idee che mi piacciono (indipendentemente da chi fossero):

  • Il modulo ui, parla al modulo di business logic per creare, aggiornare, eliminare e ottenere entità.
  • Queste entità possono trovarsi in vari stati (non avviati, in attesa, avviati, conclusi così come pochi altri)
  • Il modulo di business logic deve consolidare le fonti in un modello unificato per il modulo UI (poiché non vogliamo che il modulo UI si occupi dei dettagli nitidi delle fonti di entità).

Alcune idee che non sono:

UI layer should manage the state of the domain objects

NO. Qui sono d'accordo con te sul fatto che l'interfaccia utente non dovrebbe sapere che gli oggetti dominio esistono. Dovrebbe solo sapere come richiedere le cose attraverso la logica del controller e come visualizzare le risposte dalla logica del presentatore. L'interfaccia utente non dovrebbe essere in grado di toccare direttamente tali oggetti del dominio. Se l'interfaccia utente può toccarli, il dominio non è incapsulato correttamente.

I argued that the business logic module should maintain an FSM for each entity, such that the UI layer can issue a command to the business logic layer for a given entity, and that command will be executed if it's valid for the entities current state. If the command was valid, then the FSM would transition to a new state, executing side effect such as API calls if required.

Qui ti sei sbagliato perché stavi dando loro un disegno per le loro cose. Dovresti essere bloccato per ottenere i requisiti di comunicazione tra livelli perfezionati.

Ora, se accade il peggio e non funzionano con te, non cedere e inserire la logica nell'interfaccia utente. Crea il tuo livello tra l'interfaccia utente e le loro cose per gestire i loro shenanigans. Non impacchettare questo livello con l'interfaccia utente. Fallo e assicurati che l'interfaccia utente abbia un'API pulita che puoi testare rapidamente quando le dita iniziano a puntare.

TL; DR È necessario un argomento di progettazione del contatore migliore di "Usa FSM".

Alcuni rilanci aggiuntivi: MVC , Architettura pulita 1 , 2 , inter layer comunicazione , astrazione

    
risposta data 14.12.2018 - 00:09
fonte

Leggi altre domande sui tag