it-swarm.com.de

Werden Ereignisse nur für die GUI-Programmierung verwendet?

Werden Ereignisse nur für die GUI-Programmierung verwendet?

Wie gehen Sie bei der normalen Backend-Programmierung vor, wenn etwas mit dieser anderen Sache passiert?

57
user3093620

Nee. Sie sind sehr praktisch, um Beobachter zu implementieren und sicherzustellen, dass Klassen für Änderungen geschlossen sind.

Angenommen, wir haben eine Methode, mit der neue Benutzer registriert werden.

public void Register(user) {
    db.Save(user);
}

Dann entscheidet jemand, dass eine E-Mail gesendet werden soll. Wir könnten das tun:

public void Register(user) {
    db.Save(user);
    emailClient.Send(new RegistrationEmail(user));
}

Aber wir haben gerade eine Klasse geändert, die für Änderungen geschlossen sein soll. Wahrscheinlich in Ordnung für diesen einfachen Pseudocode, aber wahrscheinlich der Weg zum Wahnsinn im Produktionscode. Wie lange dauert es, bis diese Methode 30 Codezeilen umfasst, die kaum mit dem ursprünglichen Zweck der Erstellung eines neuen Benutzers zusammenhängen?

Es ist viel schöner, die Klasse ihre Kernfunktionalität ausführen zu lassen und ein Ereignis auszulösen, das jedem, der zuhört, mitteilt, dass ein Benutzer registriert wurde, und er kann alle erforderlichen Maßnahmen ergreifen (z. B. eine E-Mail senden).

public void Register(user) {
    db.Save(user);

    RaiseUserRegisteredEvent(user);
}

Dies hält unseren Code sauber und flexibel. Eines der oft übersehenen Teile von OOP ist, dass Klassen Nachrichten aneinander senden. Ereignisse sind diese Nachrichten.

106
RubberDuck

Nee.

Ein klassisches Beispiel für Ereignisse, die in Nicht-GUI-Logik verwendet werden, sind Datenbank-Trigger.

Trigger sind Code, der ausgeführt wird, wenn ein bestimmtes Ereignis eintritt (INSERT, DELETE usw.). Scheint mir ein Ereignis zu sein.

Dies ist die Wikipedia-Definition des Ereignisses:

Beim Rechnen ist ein Ereignis eine Aktion oder ein Ereignis, das von Software erkannt wird und von der Software verarbeitet werden kann. Computerereignisse können vom System, vom Benutzer oder auf andere Weise generiert oder ausgelöst werden. In der Regel werden Ereignisse synchron mit dem Programmablauf behandelt, dh die Software verfügt möglicherweise über einen oder mehrere dedizierte Orte, an denen Ereignisse behandelt werden, häufig eine Ereignisschleife. Eine Ereignisquelle ist der Benutzer, der mit der Software beispielsweise über Tastenanschläge auf der Tastatur interagieren kann. Eine andere Quelle ist ein Hardwaregerät wie ein Timer. Software kann auch einen eigenen Satz von Ereignissen in die Ereignisschleife auslösen, z. den Abschluss einer Aufgabe zu kommunizieren. Software, die ihr Verhalten als Reaktion auf Ereignisse ändert, wird als ereignisgesteuert bezeichnet, häufig mit dem Ziel, interaktiv zu sein.

Nicht alle Ereignisse werden vom Benutzer generiert. Einige werden von einem Timer wie einem Crontab von einer Datenbank INSERT generiert, wie ich bereits erwähnt habe.

Die Definition besagt auch, dass einige Programme oder Systeme "ereignisgesteuert, oft mit dem Ziel, interaktiv zu sein" sind, woraus man ableiten kann, dass der Zweck oder die Nützlichkeit von Ereignissen nicht nur, sondern eher häufig sind , um Interaktivität bereitzustellen (wie GUIs, obwohl dies nicht unbedingt GUIs sind, da CLI-Programme auch interaktiv sein können).

53

Die ereignisbasierte Programmierung wird tatsächlich auch für die leistungsstarke Serverprogrammierung verwendet.

Bei einer typischen Server-Workload kommt ein Großteil der Zeit für die Verarbeitung eines Ergebnisses tatsächlich von E/A. Das Abrufen von Daten von einem Festplattenlaufwerk (7200 U/min) kann beispielsweise bis zu 8,3 ms dauern. Für einen modernen GHz-Prozessor würde dies ~ 1 Million Taktzyklen entsprechen. Wenn eine CPU jedes Mal auf die Daten warten würde (nichts tun würde), würden wir eine Menge Taktzyklen verlieren.

Herkömmliche Programmiertechniken umgehen dies, indem sie mehrere Threads einführen. Die CPU versucht, Hunderte von Threads gleichzeitig auszuführen. Das Problem dieses Modells ist jedoch, dass jedes Mal, wenn eine CPU den Thread wechselt, Hunderte von Taktzyklen erforderlich sind, um Kontextwechsel . Ein Kontextwechsel ist, wenn die CPU den Thread-lokalen Speicher in die CPU-Register kopiert und auch das Register/den Status des alten Threads im RAM speichert.

Zusätzlich muss jeder Thread eine bestimmte Menge an Speicher zum Speichern seines Status belegen.

Heute gab es einen Push für Server mit einem einzelnen Thread, der in einer Schleife ausgeführt wird. Dann werden Arbeitsstücke auf ein Nachrichtenpumpe verschoben, das als Warteschlange für den einzelnen Thread fungiert (ähnlich wie bei einem UI-Thread). Anstatt auf den Abschluss der Arbeit zu warten, setzt die CPU ein Rückrufereignis für Dinge wie den Zugriff auf das Festplattenlaufwerk. Das reduziert die Kontextumschaltung.

Das beste Beispiel für einen solchen Server ist Node.js , von dem gezeigt wurde, dass er 1 Million gleichzeitige Verbindungen mit bescheidener Hardware verarbeiten kann, während ein Java/ Tomcat -Server dies tun würde kämpfen um ein paar tausend.

27
ArTs

Ereignisse werden auch häufig in der Netzwerkprogrammierung verwendet (z. B. Nginx), um teure Wartezeiten zu vermeiden und stattdessen eine saubere Schnittstelle bereitzustellen, um genau zu wissen, wann eine bestimmte Operation ausgeführt wird ist verfügbar (E/A, dringende Daten usw.). Dies ist auch eine Lösung für das C10k-Problem .

Die Grundidee besteht darin, dem Betriebssystem eine Reihe von Sockets (d. H. Netzwerkverbindungen) zur Überwachung auf Ereignisse bereitzustellen, die alle oder nur einige, an denen Sie besonders interessiert sind (z. B. zum Lesen verfügbare Daten). Wenn eine solche Aktivität vom Betriebssystem an einem der Sockets in der Liste erkannt wird, erhalten Sie eine Benachrichtigung über das Ereignis, nach dem Sie von der API gesucht haben. Anschließend müssen Sie herausfinden, woher es kommt, und entsprechend handeln .

Dies ist eine einfache und abstrakte Ansicht, die außerdem schwierig zu skalieren ist. Es gibt jedoch viele übergeordnete Frameworks, die sich sogar plattformübergreifend damit befassen: Twisted für Python, Boost.Asio für C++ oder libevent für C kommen mir in den Sinn.

10
edmz

Eingebettete Systeme sind fast immer von Natur aus ereignisgesteuert, auch wenn sie nicht explizit als solche programmiert sind.

Diese Ereignisse sind auf Hardware-Interrupts, Tastendrücke, analoge/digitale Periodenablesungen, Ablaufzeiten des Timers usw. zurückzuführen.

Embedded-Systeme mit geringem Stromverbrauch sind mit noch größerer Wahrscheinlichkeit ereignisgesteuert. Sie verbringen die meiste Zeit mit Schlafen (CPU schläft im Energiesparmodus) und warten darauf, dass etwas passiert (dieses "Etwas" ist ein Ereignis).

Eines der gängigsten und beliebtesten Frameworks für ereignisgesteuerte eingebettete Systeme ist das Quantum Platform (QP) (das QP funktioniert auch unter Linux, Windows und jedem Unix-ähnlichen Betriebssystem.) Zustandsautomaten sind eine Selbstverständlichkeit Geeignet für ereignisgesteuerte Programmierung, da das Programm nicht im typischen Sinne "sequentiell" ist, sondern eine Reihe von "Rückrufen", die je nach Systemstatus und aktuellem Ereignis aufgerufen werden.

5
Radian

Ereignismeldungen Gregor Hohpe.

Event Driven Architectures Gregor Hohpe.

SEDA-Architektur , Walisisch, Culler, Brauer.

wie gehen Sie bei der normalen Backend-Programmierung vor, wenn etwas passiert?

Finite State Machine ist ein gängiger Ansatz

Given(State.A)
When(Event.B)
Then(State.C)
    .and(Consequences.D)
3
VoiceOfUnreason

Für nicht eingebettete Systeme, aber etwas, das ich in C # gemacht habe, war das SCADA-System. Es gab viele Ereignisse, die mit dem Geschehen im Warehouse verbunden waren, als das Laden eines Teils des vom System generierten Ereignisses entladen wurde und ein anderer Teil einen neuen Status in die Datenbank schrieb. Wir hatten natürlich einen GUI-Client, aber er diente nur dazu, den Status der Datenbank anzuzeigen, der den Status des Lagers widerspiegelte. Es war also eine Backend-Server-Software, die auf Ereignissen und Threading basierte. Ziemlich herausfordernd zu entwickeln.

https://en.wikipedia.org/wiki/SCADA

0
Mateusz

In eingebetteten Systemen treten Ereignisse während Interrupts auf. Es gibt viele Interruptquellen, von Timern bis zu E/A.

Außerdem kann RTOS kann auch Ereignisse enthalten. Ein Beispiel wartet auf eine Nachricht von einer anderen Aufgabe.

0
Thomas Matthews