Programmazione di domande strutturali, controllo di molti stati e transizioni specifiche tra gli stati caso per caso

2

Questa è una domanda di teoria per me solo per cercare di scrivere un codice migliore. Sono abbastanza nuovo quindi spero di usare termini come lo stato nel modo corretto.

Come dovrei pensare a questo problema? Sto codificando qualcosa che funziona, ma qualunque cosa faccia, sembra complicata, difficile da capire e difficile da modificare.

Sto riproducendo un video clip con un ID, voglio anche che sia in grado di passare dinamicamente a una visualizzazione in miniatura di quel video. Voglio essere in grado di impostare questo video anche in bianco e chiudere tutte le connessioni che non sono necessarie, sto cercando di fare tutto questo in modo efficiente - non riconnettersi al server quando non ho bisogno di ecc.

così ho -

connected - > on / off

ID video - > una stringa

modalità - > streaming video / anteprima / disabilitato

Spero che vedrai il mio dilemma con alcuni esempi -

Caso 1. L'utente inizia da capo e desidera visualizzare una miniatura del video "a"

-Connetti al server per "a", invia la richiesta per la miniatura, attiva l'oggetto miniatura.

Caso 2. L'utente inizia a visualizzare una miniatura del video "a" e desidera iniziare a guardare un flusso di video "b"

-compare le stringhe "a" e "b" - vedi che sono diverse. nascondi l'oggetto miniatura e cancella il suo buffer. Disconnettersi dal server per "a" e connettersi al server "b". avvia lo streaming video, attiva l'oggetto video, richiedi le miniature dal server, quindi viene caricato in memoria nel caso in cui l'utente desideri passare alla modalità miniatura.

Caso 3. L'utente sta guardando un flusso di "b" e desidera visualizzare una miniatura di "b"

-strarre le stringhe "b" e "b" - vedere che sono uguali e rimanere connessi al server, nascondere l'oggetto video e interrompere lo streaming, attivare l'oggetto miniatura, inviare un'altra richiesta al server per la miniatura ...

Tutte queste opzioni stanno facendo la mia testa, voglio che scelga il modo più efficace per passare da uno stato all'altro, ma tutte le diverse opzioni mi stanno confondendo. Immagino che sto cercando aiuto su quale sia il modo migliore per strutturare questo, perché quello che sto facendo al momento sembra molto confuso, finisco con un enorme albero di if annidati di un sacco di casi specifici e poi patch su dove va male.

if (connected but used to be disconnected) { 
    if (mode streaming but used to be thumbnail) {...
    if (mode streaming but used to be streaming) {...

if (connected but used to be connected) {....

if (disconnected but used to be connected) {....

if (disconnected but used to be disconnected) {...

va avanti all'infinito ..

    
posta pjackson 06.08.2013 - 07:30
fonte

2 risposte

6

Incapsula ogni stato non banale in una classe di stato separata che sa come passare da uno stato all'altro. Quando si verifica una transizione, l'oggetto di stato cambia. Ad esempio, da "ConnectedState" a "DisconnectedState".

Modella il tuo problema come macchina di stato . Sono un grande fan del modello di stato per risolvere questi problemi.

    
risposta data 06.08.2013 - 10:22
fonte
2

Martin Wickman ha ragione nel suggerire uno stato macchina.

Sembra che tu possa trarre beneficio dall'annidamento di alcune delle tue informazioni di stato (es. stato di connessione) - nidificare significa che i tuoi stati sovraordinati avranno macchine di stato interne - nel qual caso potresti voler controllare < a href="http://en.wikipedia.org/wiki/UML_state_machine"> Macchine dello stato UML .

Le macchine a stati UML sono più complesse delle normali macchine a stati finiti e, secondo la mia esperienza, sono piuttosto ingombranti da implementare a mano. In alternativa, per ripulire ciò che hai ora e passare a un'implementazione più OOPish, puoi provare questo:

Dividi le cose in tre o quattro funzioni ortogonali:

  • Una funzione di determinazione dello stato successivo - questo richiederebbe lo stato corrente della macchina e il suo input corrente e determinerebbe quale dovrebbe essere il successivo stato della macchina
  • Una funzione di output di transizione - questo dovrebbe esaminare quale transizione di stato è stata presa, insieme con l'input, e reagire ad essa (paragonabile all'output di una macchina Mealy)
  • Una funzione di output di stato - questo dovrebbe guardare lo stato corrente e l'output per esso (paragonabile all'output di una macchina Moore)
  • Una funzione di transizione: chiama le altre tre funzioni e imposta lo stato della macchina

Esempio:

func getNextState(input, curr_state)
{
    if (curr_state == STATE_FOO)
    {
        if (input == fizz)
            return STATE_FIZZ
        else
            return STATE_BUZZ
    }
    else if (curr_state == STATE_BAR)
    {
        ...
    }
    else
    {
        return STATE_DONE
    }
}

func outputForTransition(input, prev_state, next_state)
{
    if (prev_state == STATE_FIZZ && next_state == STATE_BUZZ)
    {
        print "Fizz Buzz"
    }
    else if (prev_state == STATE_FOO && next_state == STATE_BAR)
    {
        ...
    }
}

func outputForState(curr_state)
{
    switch(curr_state)
    {
        case STATE_FOO:
            foo()
        case STATE_BAR:
            bar()
        case STATE_FIZZ:
            fizz()
        case STATE_BUZZ:
            buzz()
    }
}

func transitionStates(input)
{
    prev_state = curr_state
    curr_state = getNextState(input, curr_state)

    // you could use either or both output functions:
    outputForTransition(input, prev_state, curr_state)
    outputForState(curr_state)
}

Potrebbe sembrare ancora un po 'disordinato, ma credimi chiarisce un po' le cose.

(E ovviamente vorresti implementare quanto sopra dopo aver elaborato il tuo diagramma di stato.)

    
risposta data 06.08.2013 - 23:00
fonte

Leggi altre domande sui tag