Macchine a stati finiti in .NET
Le macchine a stati finiti sono basate sulla ripetizione automatica di un insieme di istruzioni, per lo più collegate alla raccolta di un input esterno, per svolgere attività di riconoscimento e controllo. Si tratta di modelli matematici capaci di interpretare situazioni reali e che necessitano al loro interno di rilevare lo stato corrente in cui si trova la macchina stessa, per controllare il codice eseguito ad ogni iterazione.
Quindi abbiamo lo stato Corrente ed un gestore che viene chiamato ad ogni iterazione della macchina, finché non si produce un qualche cambiamento di stato, che potrebbe essere rilevato da un segmento di codice diverso.
Si potrebbe dover ricorrere ad una macchina a stati in .NET per emulare le così dette coroutines all'interno di un IEnumerator ricorsivo, che ritorna ad esempio un FileSystemInfo per tutti i file e le directory partendo da una certa posizione del filesystem: la macchina a stati, per leggere le informazioni, eseguire iterativamente la stessa operazione fino ad esaurire tutto il contenuto di tutti gli oggetti del contenitore, avrà bisogno di sapere quando entrerà in un certo stato, diverso da quelo iniziale, per interrompere l'ingrato compito.
La macchina riceve informazioni e sulla base di quelle decide se procedere o fermarsi; una situazione in cui si fa fatica a distinguere tra produttore e consumatore tra due porzioni di codice che interagiscono, potremmo pensare a una sorta di ciclo for condizionato.
Dettagli sulle coroutines si trovano in "The Art of Computer Programming Vol. 1" di Donald Knuth.
Si potrebbe implementare una macchina a stati finiti tramite una enum che contiene il nome di ciascuno stato e un grosso switch per gestire ogni enum. Se non ci fosse bisogno di manutenzione potrebbe anche sembrare efficiente.
D'altra parte, se è vero che un oggetto rappresenta un insieme di stati, si potrebbe pensare di adottare un modello object oriented e cambiare stato modificando l'oggetto CurrentState; in questa ottica, il gestore di stato sarebbe un metodo standard, più semplice da leggere rispetto ad una lunga istruzione switch.
L'inerfaccia tra enumeratore e state machine si ottiene attraverso metodi tipo reset() per tornare allo stato iniziale, moveNext() per iterare la state machine, eventualmente settando un campo currentValue a true o false a sonda che ci siano o meno altri item.
Poiché la gestione degli stati comporta la variazione di un campo private, che indica il CurrentState, il gestore di stato potrebbe essere un metodo virtuale, oppure si potrebbe usare un'interfaccia. Per questo la soluzione proposta da Jon Shemitz in un articolo su Informit contiene anche una classe astratta che si aspetta il supporto dell'interfaccia IStateHandler da parte delle classi di gestione.
Con l'utilizzo della programmazione ad oggetti invece del classico metodo enum + switch si facilitano il debugging e la manutenzione del codice.
Questo è il link per scaricare il codice completo dell'esempio. L'autore avverte che quando uscirà Whidbey, i cosiddetti iterator dovrebbero eliminare la necessità di emulare le coroutines, d'altra parte potrebbero esserci altre necessità non coperte dagli iteratori e c'è ancora tempo prima di vedere Whidbey.NET.
Articolo tratto da Programmazione.it
- [15/02/11] HP e webOS nei PC
- [16/04/10] Cinque nuovi modelli di autoradio multimediali da Pioneer
- [02/07/08] Mio Moov 380: GPS ed internet in macchina
- [18/02/05] Cellulari, un codice di autodisciplina che tutela i minori
- [20/03/04] Arrivano le Robolimpiadi