Gli eventi sono utilizzati solo per la programmazione della GUI?
Come gestisci la normale programmazione di backend quando succede qualcosa a quest'altra cosa?
Gli eventi sono utilizzati solo per la programmazione della GUI?
Come gestisci la normale programmazione di backend quando succede qualcosa a quest'altra cosa?
No. Sono davvero utili per implementare gli osservatori e fare in modo 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 deve essere inviata un'email. Potremmo fare questo:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
Ma abbiamo appena modificato una classe che dovrebbe essere chiusa alle modifiche. Probabilmente va bene per questo semplice pseudo-codice, ma probabilmente il modo per impazzire nel codice di produzione. Quanto tempo impiega questo metodo per 30 righe di codice a malapena correlate allo scopo originale di creare un nuovo utente ??
È molto più bello lasciare che la classe esegua le sue funzionalità di base e generare un evento che indichi a chiunque abbia ascoltato che un utente è stato registrato e può intraprendere qualsiasi azione (come inviare un messaggio di posta elettronica).
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
Ciò mantiene il nostro codice pulito e flessibile. Uno dei pezzi di OOP spesso trascurati è che le classi inviano messaggi tra loro. Gli eventi sono questi messaggi.
No.
Un classico esempio di eventi usati nella logica non-GUI sono i trigger del database.
I trigger sono codice che viene eseguito quando si verifica un determinato evento (INSERT, DELETE, ecc.). Sembra un evento per me.
Questa è la definizione di Wikipedia dell'evento:
In computing, an event is an action or occurrence recognized by software that may be handled by the software. Computer events can be generated or triggered by the system, by the user or in other ways. Typically, events are handled synchronously with the program flow, that is, the software may have one or more dedicated places where events are handled, frequently an event loop. A source of events includes the user, who may interact with the software by way of, for example, keystrokes on the keyboard. Another source is a hardware device such as a timer. Software can also trigger its own set of events into the event loop, e.g. to communicate the completion of a task. Software that changes its behavior in response to events is said to be event-driven, often with the goal of being interactive.
Non tutti gli eventi sono generati dall'utente. Alcuni sono generati da un timer come un crontab di un database INSERT come ho detto prima.
La definizione indica anche che alcuni programmi o sistemi sono "basati sugli eventi, spesso con l'obiettivo di essere interattivi" , da cui si può ricavare che lo scopo o l'utilità degli eventi non sono solo, ma piuttosto spesso, per fornire interattività (come GUI anche se 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 ad alte prestazioni.
In un tipico carico di lavoro del server, la maggior parte del tempo di elaborazione di un risultato deriva effettivamente dall'I / O. Ad esempio, l'estrazione di dati da un disco rigido (7200 RPM) può richiedere fino a 8,3 ms. Per un moderno processore GHz, equivale a ~ 1 milione di cicli di clock. Se una CPU dovesse attendere i dati ogni volta (senza fare nulla), perderemmo un sacco di cicli di clock.
Le tecniche di programmazione tradizionali aggirano questo problema introducendo più discussioni . La CPU tenta di eseguire contemporaneamente centinaia di thread. Tuttavia, il problema di questo modello è che, ogni volta che una CPU cambia thread, richiede centinaia di cicli di clock per switch di contesto . Un interruttore di contesto si verifica quando la CPU copia la memoria locale del thread nei registri della CPU e memorizza anche il registro / stato del thread precedente nella RAM.
Inoltre, ogni thread deve utilizzare una certa quantità di memoria per memorizzare il suo stato.
Oggi, c'è stato un push per i server che ha un singolo thread, che gira in un loop. Poi i pezzi di lavoro vengono inseriti in un messaggio pompa , che funge da coda per il singolo thread (molto simile a un'interfaccia utente filo). Invece di aspettare che il lavoro finisca, la CPU imposta un evento di callback, per cose come l'accesso all'hard disk. Che riduce il cambio di contesto.
Il miglior esempio di tale server è Node.js , che è stato dimostrato in grado di gestire 1 milione di connessioni simultanee con hardware modesto, mentre un server Java / Tomcat farebbe fatica a poche migliaia.
Gli eventi sono anche molto utilizzati nella programmazione di rete (ad esempio Nginx) per evitare costosi cicli di attesa-attesa e invece forniscono un'interfaccia pulita per sapere esattamente quando è disponibile una determinata operazione (I / O, urgente dati ecc.). Questa è anche una soluzione al problema C10k .
L'idea di base è quella di fornire al sistema operativo una serie di socket (cioè 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 vista di basso livello e astratta, inoltre difficile da ottenere una buona scalabilità. Tuttavia ci sono molti framework di livello superiore che si occupano di questo in modo persino multipiattaforma: Twisted per Python, Boost.Asio per C ++ o libevent per C mi vengono in mente.
I sistemi embedded sono quasi sempre intrinsecamente guidati dagli eventi, anche se non sono programmati esplicitamente come tali.
Questi eventi provengono da cose come interruzioni hardware, pressioni di pulsanti, letture analogico-digitali periodiche, scadenze temporali, ecc.
I sistemi embedded a bassa potenza hanno ancora più probabilità di essere guidati dagli eventi; trascorrono la maggior parte del tempo dormendo (la CPU dorme in modalità a basso consumo), aspettando che qualcosa accada (che "qualcosa" è un evento).
Uno dei framework più comuni e diffusi per i sistemi embedded event-driven è Quantum Platform (QP) (il QP funziona anche con Linux, Windows e qualsiasi sistema operativo unix.) Le macchine di stato sono una scelta naturale per la programmazione basata sugli eventi, poiché il programma non è "sequenziale" nel senso tipico, piuttosto è un insieme di "callback" che vengono invocati in base allo stato del sistema e all'evento corrente.
Messaggi di eventi Gregor Hohpe.
Architetture basate su eventi Gregor Hohpe.
architettura SEDA , gallese, Culler, Brewer.
how do you handle in normal backend programming when something happens do this other thing?
Macchina a stati finiti è un approccio comune
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
Nei sistemi embedded, gli eventi si verificano durante gli interrupt. Esistono molte fonti di interrupt, dai timer all'I / O.
Inoltre, RTOS può avere anche eventi. Un esempio è in attesa di un messaggio da un'altra attività.
Per sistemi non incorporati, ma qualcosa che stavo facendo in C # era il sistema SCADA. Ci sono stati molti eventi collegati a ciò che stava accadendo nel magazzino quando il carico è stato scaricato parte dell'evento generato dal sistema e l'altra parte stava scrivendo un nuovo stato nel database. Ovviamente 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. Piuttosto impegnativo da sviluppare.
Leggi altre domande sui tag programming-languages theory asynchronous-programming event-programming