Gli eventi vengono utilizzati solo per la programmazione della GUI?
Come gestite la normale programmazione back-end quando succede qualcosa a quest'altra cosa?
Gli eventi vengono utilizzati solo per la programmazione della GUI?
Come gestite la normale programmazione back-end quando succede qualcosa a quest'altra cosa?
Risposte:
No. Sono davvero utili per implementare gli osservatori e assicurarsi che le classi siano chiuse alle modifiche.
Diciamo che abbiamo un metodo che registra i nuovi utenti.
public void Register(user) {
db.Save(user);
}
Quindi qualcuno decide che è necessario inviare un'e-mail. Potremmo farlo:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
Ma abbiamo appena modificato una classe che dovrebbe essere chiusa alla modifica. Probabilmente va bene per questo semplice pseudo-codice, ma probabilmente la via della follia nel codice di produzione. Quanto tempo ci vorrà prima che questo metodo sia composto da 30 righe di codice che sono appena correlate allo scopo originale di creare un nuovo utente ??
È molto più bello lasciare che la classe esegua le sue funzionalità principali e organizzare un evento dicendo a chiunque stia ascoltando che un utente è stato registrato e possono intraprendere qualsiasi azione necessaria (come inviare un'e-mail).
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
Ciò mantiene il nostro codice pulito e flessibile. Uno dei pezzi spesso trascurati di OOP è che le classi si scambiano messaggi . Gli eventi sono questi messaggi.
No.
Un classico esempio di eventi utilizzati nella logica non GUI sono i trigger di database.
I trigger sono codici che vengono eseguiti quando si verifica un determinato evento (INSERT, DELETE, ecc.). Mi sembra un evento.
Questa è la definizione di evento di Wikipedia:
Nell'informatica, un evento è un'azione o occorrenza riconosciuta dal software che può essere gestita dal software. Gli eventi del computer possono essere generati o attivati dal sistema, dall'utente o in altri modi. In genere, gli eventi vengono gestiti in modo sincrono con il flusso del programma, ovvero il software può avere uno o più posti dedicati in cui gli eventi vengono gestiti, spesso un ciclo di eventi. Una fonte di eventi include l'utente, che può interagire con il software tramite, ad esempio, la pressione dei tasti sulla tastiera. Un'altra fonte è un dispositivo hardware come un timer. Il software può anche attivare il proprio set di eventi nel loop degli eventi, ad esempio per comunicare il completamento di un'attività. Si dice che il software che modifica il suo comportamento in risposta agli eventi sia guidato dagli eventi, spesso con l'obiettivo di essere interattivo.
Non tutti gli eventi sono generati dall'utente. Alcuni sono generati da un timer come una crontab di un database INSERT come ho detto prima.
La definizione afferma inoltre che alcuni programmi o sistemi sono "guidati dagli eventi, spesso con l'obiettivo di essere interattivi" , da cui si può derivare che lo scopo o l'utilità degli eventi non sono solo, ma piuttosto spesso, fornire interattività (come le GUI sebbene non necessariamente GUI, poiché i programmi CLI possono anche essere interattivi).
La programmazione basata su eventi viene effettivamente utilizzata anche per la programmazione di server altamente performanti.
In un tipico carico di lavoro del server, la maggior parte del tempo che elabora un risultato proviene effettivamente dall'I / O. Ad esempio, l'estrazione di dati da un'unità disco rigido (7200 RPM) può richiedere fino a 8,3 ms. Per un moderno processore GHz, ciò equivarrebbe a ~ 1 milione di cicli di clock. Se una CPU dovesse aspettare i dati ogni volta (senza fare nulla), perderemmo MOLTI cicli di clock.
Le tecniche di programmazione tradizionali aggirano questo problema introducendo più thread . La CPU tenta di eseguire centinaia di thread contemporaneamente. Tuttavia, il problema di questo modello è che, ogni volta che una CPU cambia thread, richiede il cambio di contesto per centinaia di cicli di clock . Un interruttore di contesto è quando la CPU copia la memoria thread-local nei registri della CPU e memorizza anche il registro / stato del thread precedente nella RAM.
Inoltre, ogni thread deve consumare una certa quantità di memoria per memorizzare il suo stato.
Oggi c'è stata una spinta per i server che ha un singolo thread, che gira in un ciclo. Quindi i pezzi di lavoro vengono inseriti in un pump dei messaggi , che funge da coda per il singolo thread (proprio come in un thread dell'interfaccia utente). Invece di attendere il completamento del lavoro, la CPU imposta un evento di richiamata, per cose come l'accesso al disco rigido. Ciò riduce il cambio di contesto.
Il miglior esempio di tale server è Node.js , che ha dimostrato di essere in grado di gestire 1 milione di connessioni simultanee con hardware modesto, mentre un server Java / Tomcat avrebbe difficoltà a qualche migliaio.
Gli eventi sono anche ampiamente utilizzati nella programmazione di rete (ad es. Nginx) per evitare costosi loop di attesa e fornire invece un'interfaccia pulita per sapere esattamente quando è disponibile una determinata operazione (I / O, dati urgenti ecc.). Questa è anche una soluzione al problema C10k .
L'idea di base è fornire al sistema operativo un set di socket (ad es. Connessioni di rete) per monitorare gli eventi, tutti o solo alcuni a cui sei particolarmente interessato (dati disponibili per la lettura, ad esempio); quando tale attività viene rilevata dal sistema operativo su uno dei socket nell'elenco, riceverai una notifica dell'evento che stavi cercando dall'API, che dovrai quindi risolvere da dove proviene e agire di conseguenza .
Ora, questa è una visione di basso livello e astratta, inoltre difficile da scalare bene. Tuttavia, ci sono molti framework di livello superiore che affrontano questo problema in modo uniforme e multipiattaforma: Twisted for Python, Boost.Asio per C ++ o libevent per C mi vengono in mente.
I sistemi integrati sono quasi sempre intrinsecamente guidati da eventi, anche se non sono programmati esplicitamente come tali.
Questi eventi provengono da cose come interruzioni hardware, pressioni di pulsanti, letture periodiche da analogico a digitale, scadenze del timer, ecc.
I sistemi embedded a bassa potenza hanno ancora più probabilità di essere guidati da eventi; trascorrono la maggior parte del loro tempo a dormire (CPU in modalità a basso consumo), in attesa che accada qualcosa (quel "qualcosa" è un evento).
Uno dei framework più comuni e popolari per i sistemi embedded basati su eventi è la Quantum Platform (QP) (il QP funziona anche con Linux, Windows e qualsiasi sistema operativo simile a unix.) Le macchine a stati sono una scelta naturale per la programmazione basata su eventi, poiché il programma non è "sequenziale" nel senso tipico, piuttosto, è un insieme di "callback" che vengono invocati a seconda dello stato del sistema e dell'evento corrente.
Messaggi di evento Gregor Hohpe.
Architetture guidate da eventi Gregor Hohpe.
Architettura SEDA , gallese, Culler, Brewer.
come gestisci nella normale programmazione back-end quando succede qualcosa, fai quest'altra cosa?
La macchina a stati finiti è un approccio comune
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
Nei sistemi integrati, si verificano eventi durante gli interrupt. Esistono molte fonti di interrupt, dai timer all'I / O.
Inoltre, RTOS può contenere anche eventi. Un esempio è in attesa di un messaggio da un'altra attività.
Per il sistema non incorporato, ma qualcosa che stavo facendo in C # era il sistema SCADA. Ci sono stati molti eventi legati a ciò che stava accadendo nel magazzino quando il carico veniva scaricato parte dell'evento generato dal sistema e l'altra parte stava scrivendo il nuovo stato nel database. Naturalmente avevamo un client GUI ma era solo per mostrare lo stato del database che rifletteva lo stato del magazzino. Quindi era un software server back-end basato su eventi e threading. Abbastanza stimolante da sviluppare.