Identificazione del modello.
Questo modello è in realtà piuttosto intelligente. In effetti è così utile che Microsoft abbia scritto una libreria considerevole e ben gradita chiamata Estensioni reattive per risolvere questo problema utilizzando una tecnica chiamata programmazione reattiva funzionale . Il pattern che stai cercando di nominare è chiamato Observable .
Generalizza fondamentalmente un IEnumerable
. Hai una collezione di elementi che ti piacerebbe steam attraverso una serie di trasformazioni come mappatura, aggregazione di filtri e così via. Tuttavia, anche tu hai un Task
fondamentalmente poiché hai un'azione dipendente dal tempo che non è immediatamente disponibile.
Fondamentalmente abbiamo un grafico che va in questo modo:
| Singular | Plural
------------------------------------------------
Spatial | Value | Enumerable<Value>
Temporal | Task<Value> | Observable<Value>
Concettualmente un osservabile è ciò che modella il tuo problema . Ci sono state molte ricerche su questo e dovresti davvero evitare di inventare la ruota, se possibile. Il flusso di utilizzo di un osservabile è qualcosa del genere:
Il flusso di lavoro quando si utilizza un osservabile
Link a esempi reali più tardi.
-
Si inizia con una fonte , ad esempio un timer o un flusso di pacchetti di dati, una funzione che esegue una richiesta ogni pochi secondi o una serie di back-to-back e così via.
-
Quindi, le trasformazioni vengono applicate ad ogni turno - puoi prendere un osservabile esistente e
.Select
in un nuovo osservabile mappato o .Where
in un filtro. Puoi anche rimuoverlo, flatMap ed eseguire trasformazioni interessanti. Questo è come LINQ solo LINQ rappresenta una singola query differita una volta in cui un Observable rappresenta un processo in corso.
-
Puoi scartare l'osservabile iscrivendoti ad esso, eseguendo una funzione alla sua fine.
-
Puoi eseguire il fork di un osservabile creando non solo "elenchi di nodi" ma interi alberi.
Questo concetto di osservabile funzionale che le catene non è solo più potente degli eventi e si aggrega bene (puoi unire osservabili, testarli facilmente e così via) - è anche molto semplice. Il tuo codice può essere simile a:
GetDataItems() // returns a new observable
.Where(IWantItemsForTheNextRound) // filtering logic
.Select(Mapper) // mapping logic
... // any more transformations
Proprio come lavorare con IQueryable
in LINQ, le vecchie trasformazioni non interessano e non sono a conoscenza di ciò che è passato da quel momento in poi. Come LINQ hai una strong astrazione sull'elaborazione di una collezione, solo che questa volta è necessario del tempo.
Puoi inserire un nodo nel mezzo mettendo un gancio per esso e iniettando una funzione che fa qualcosa con quel gancio - se ti appiattisci su quella mappa puoi mettere la logica arbitrariamente complicata là estendendola quanto vuoi.
Teoria e lettura attuali.
Vi è abbondanza di materiale teorico sul perché questo approccio sia molto efficace in gor di KrisKowal o in Dualità e la fine del reattivo .