イベントはGUIプログラミングにのみ使用されますか?


57

イベントはGUIプログラミングにのみ使用されますか?

他の何かに何かが起こった場合、通常のバックエンドプログラミングではどのように処理しますか?


6
ところで、イベントソースは、イベントプログラミングとは完全に直交する概念です。イベントソーシングの基本概念は、システムの「状態」を保存するのではなく、「イベント」または「変更」をシステムに保存することです。たとえば、a)残高(STATE)またはb)一連のトランザクション(EVENTSOURCE)として銀行口座をモデル化できます。
ARTS

4
使用法にもよりますが、「イベント」は通常、シュガーでラップされたコールバックの単なる形式です。コールバックはどこでも使用されます-もし興味があれば、それはおそらく検索を始めるのに良いキーワードです。
J ...

10
また、マイクロコントローラのように低レベルになっても、ハードウェア割り込みは有用で議論の余地のない重要な機能であることがわかります。制御システム、またはコーヒーメーカーのような基本的なIOに最適です。これらのハードウェア割り込みは、実際にはイベントと本質的に違いはありません。
ダン

いや!実用例:Nodejsイベント
-sampathsris

2
Windowsを使用していますか?イベントビューアをご覧ください。楽しんで。
-Marc.2377

回答:


106

いや。それらは、オブザーバーを実装し、クラスが変更されないようにするのに本当に便利です。

新しいユーザーを登録するメソッドがあるとします。

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

その後、誰かがメールを送信することを決定します。これを行うことができます:

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

しかし、修正に閉じられることになっているクラスを修正しました。この単純な擬似コードにはおそらく問題ありませんが、本番コードの狂気への道はおそらくあります。このメソッドが、新しいユーザーを作成する本来の目的とほとんど関係のない30行のコードになるまで、どのくらいかかりますか?

クラスにコア機能を実行させ、ユーザーが登録されたことを聞いている人に通知するイベントを発生させ、実行する必要のあるアクション(電子メールの送信など)を実行できると、はるかに優れています。

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

    RaiseUserRegisteredEvent(user);
}

これにより、コードがクリーンで柔軟になります。よく見落とされがちなOOPの1つは、クラスが互いにメッセージを送信することです。イベントはこれらのメッセージです。


37
これを読んで「ブッキングの作成」コードを考えて、しばらく泣き、より良い場所を
待ち望んでい

1
+1、素晴らしい答え。ちょっとした質問(これは少し気になりました):メソッド名(登録、保存、送信)を大文字で始めた特別な理由はありますか?もちろん、これはこの回答の有用性には影響しません。
ペドロA

14
@Hamsteriffic私はほとんどがC#開発者であり、一般的に受け入れられている慣習です。他の理由はありません。
ラバーダック

6
@Hamsterifficasは、lowerCaseと呼ばれますが、途中に大文字が含まれているものは、キャメルケースと呼ばれます。これは、いくつかの例を挙げると、pythonとほとんどのシェル言語でよく知られているアンダースコアで小文字の単語が区切られているsnake_caseとは異なります。
アーロン

5
イベントはこれらのメッセージの一種です。メソッド呼び出しも、メッセージパッシングと見なされることになっています。
jpmc26

53

いや。

非GUIロジックで使用されるイベントの典型的な例は、データベーストリガーです。

トリガーは、特定のイベント(INSERT、DELETEなど)が発生したときに実行されるコードです。私にとってはイベントのようです。

これはイベントのウィキペディア定義です:

コンピューティングにおいて、イベントとは、ソフトウェアによって処理される可能性のあるソフトウェアによって認識されるアクションまたは発生です。コンピューターイベントは、システム、ユーザー、またはその他の方法で生成またはトリガーできます。通常、イベントはプログラムフローと同期して処理されます。つまり、ソフトウェアには、イベントが処理される1つ以上の専用の場所(多くの場合、イベントループ)があります。イベントのソースには、ユーザーが含まれます。ユーザーは、たとえば、キーボードのキーストロークによってソフトウェアと対話できます。別のソースは、タイマーなどのハードウェアデバイスです。ソフトウェアは、たとえばタスクの完了を伝えるために、イベントループに独自のイベントセットをトリガーすることもできます。イベントに応答して動作を変更するソフトウェアは、多くの場合、インタラクティブであることを目的として、イベント駆動型と言われています。

すべてのイベントがユーザー生成されるわけではありません。前述のように、一部はcrontabのようなタイマーによって、またはデータベースINSERTによって生成されます。

定義では、一部のプログラムまたはシステムは「イベント駆動型であり、多くの場合、インタラクティブであることを目標としている」と述べており、イベントの目的または有用性は、単に対話ではなく、GUI必ずしもGUIではありませんが、CLIプログラムも対話型である可能性があります)。


2
データベーストリガーについて聞いたとき、私は常にこのことを考えます。thecodelesscode.com
Almo

DBAの元開発者として、DBの幅広いパフォーマンスを考慮せずにトリガーを使用することについて人々が話すのを聞くたびにうんざりします。
スリーバリューロジック

27

実際、イベントベースのプログラミングは、パフォーマンスの高いサーバープログラミングにも使用されます。

通常のサーバーワークロードでは、結果の処理のほとんどの時間は実際にはI / Oから来ます。たとえば、(7200 RPM)ハードディスクドライブからデータを引き出すには、最大8.3 msかかります。最新のGHzプロセッサの場合、これは100万クロックサイクルに相当します。CPUが毎回データを待機する(何もしない)場合、クロックサイクルの多くが失われます。

従来のプログラミング手法では、複数のスレッドを導入することでこれを回避しています。CPUは数百のスレッドを同時に実行しようとします。ただし、このモデルの問題は、CPUがスレッドを切り替えるたびに、コンテキストの切り替えに数百のクロックサイクルが必要になることです。コンテキストスイッチは、CPUがスレッドローカルメモリをCPUのレジスターにコピーし、古いスレッドのレジスター/状態をRAMに保存する場合です。

さらに、各スレッドは、その状態を保存するために一定量のメモリを使い果たす必要があります。

今日、単一のスレッドを持ち、ループで実行されるサーバーのプッシュが行われています。次に、作業がメッセージポンプにプッシュされます。メッセージポンプは、単一のスレッドのキューとして機能します(UIスレッドのように)。CPUは、作業が完了するのを待つ代わりに、ハードディスクドライブへのアクセスなどのコールバックイベントを設定します。コンテキストの切り替えが減少します。

そのようなサーバーの最良の例はNode.jsです。これは、控えめなハードウェアで100万の同時接続を処理できることが示されていますが、Java / Tomcatサーバーは数千で苦労します。


2
「控えめなハードウェア」は少し誤解を招く恐れがあります。OSが使用するものに加えて、Nodeには8GB以上が必要です。また、メモリが十分ある場合、Tomcatは数千の接続を簡単に処理できます。確かに、大きな違いはありますが、1000倍ではありません。
ポールドレイパー

@PaulDraperいいえ、できません。そして、それはしません。8000スレッドのスタックだけに8GB以上が必要です。それが大きな違いです。
ARTS

3
8GB以外の@PaulDraperは、サーバー標準では非常に控えめです。私は128GBのRAMを搭載したマシンで作業しましたが、それらも完全にはロードされていません。ラムスティックは、マシン全体よりも高価です。
ARTS

スタックサイズは異なります。Oracle / OpenJDKは、64ビットではほとんどのプラットフォームで1MB、32ビットでは512Kにデフォルト設定されています。デフォルトをそのまま使用する場合は、正しいでしょう。しかし、デフォルトでは、1Mノード接続に到達する方法ではありません;)とにかく、128Kで十分です。あなたはさらに少ないで逃げることができます。8000スレッドの場合、1GBのスタックスペースになります。
ポールドレーパー

6
あなたは間違っています。デフォルトのスタックサイズでも、必要な仮想メモリは8 GiBだけです。メモリは必要に応じてオンザフライでコミットされます。通常、実際に追加のメモリを使用している場合を除き、スタックごとに1ページのみが必要です。そして実際には、そのようなシステムのほとんどのスレッドには、それらの(通常)64 KBのスタックしかありません。仮想メモリの使用量は32ビットOSでは大したことですが、64ビットではそれほどではありません。TCPポートの枯渇など、他の制限にすぐに遭遇します:)そして、ノードの「疑似スタック」はどこに保存されると思いますか?そうです、ヒープ上です。
ルアーン

10

イベントはネットワークプログラミング(Nginxなど)でも頻繁に使用され、高価なビジー待機ループを回避し、代わりに特定の操作(I / O、緊急データなど)がいつ利用可能かを正確に知るためのクリーンなインターフェイスを提供します。これはC10k問題の解決策でもあります。

基本的な考え方は、イベント、すべてのイベント、または特に関心のあるイベント(たとえば、読み取り可能なデータ)を監視するためのソケットセット(ネットワーク接続)をOSに提供することです。このようなアクティビティがリスト内のソケットの1つでオペレーティングシステムによって検出されると、APIが探していたイベントの通知を取得します。次に、それがどこから来たかを整理し、それに応じて行動する必要があります。

さて、これは低レベルで抽象的なビューであり、さらに拡張性を高めるのはさらに困難です。しかし、さらにクロスプラットフォームの方法でそれを処理する多くの高レベルのフレームワークがあります。PythonではTwisted、C ++ではBoost.Asio、Cではlibeventが思い浮かびます。


+1 "高価なビジー待機ループ":言い換えると、非アクティブ(待機)を伴う並列プロセス、およびそのようなプロセス(メッセージまたはイベント)間の同期に役立ちます。現実の世界の多くは機能します。
fr13d

ソケットが元々、ネットワークが存在する前に、単一のマシン上のIPCの形式として設計されていたことを知るのは興味深いことです。

5

組み込みシステムは、明示的にプログラムされていない場合でも、ほとんど常に本質的にイベント駆動型です。

これらのイベントは、ハードウェア割り込み、ボタンの押下、アナログからデジタルへの定期的な読み取り、タイマーの期限切れなどのようなものから発生します。

低電力の組み込みシステムは、イベント駆動型である可能性がさらに高くなります。彼らはほとんどの時間をスリープ(CPUは低電力モードでスリープ)して、何かが起こるのを待っています(「何か」はイベントです)。

イベント駆動型組み込みシステムの最も一般的で人気のあるフレームワークの1つは、Quantum Platform(QP)です(QPはLinux、Windows、およびUnix系OSでも動作します)。ステートマシンは、イベント駆動型プログラミングに最適です。プログラムは典型的な意味で「シーケンシャル」ではなく、むしろ、システム状態と現在のイベントに応じて呼び出される「コールバック」のセットです。


3

イベントメッセージ Gregor Hohpe。

イベント駆動型アーキテクチャ Gregor Hohpe。

SEDAアーキテクチャ、ウェールズ、カラー、ブリューワー。

通常のバックエンドプログラミングでは、何か他のことが起こった場合、どのように対処しますか?

有限状態機械は、1つの一般的なアプローチです

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

2
1、これは実際には一貫した答えではありません。2、FSMはイベント使用の良い例ではありません。
whatsisname

1
FSM。パスタファリアの宗教は多くの出来事を観察していると確信しています;-)
fr13d

0

組み込みシステムでは、割り込み中にイベントが発生します。タイマーからI / Oまで、多くの割り込みソースがあります。

また、RTOSはイベントも持つことができます。1つの例は、別のタスクからのメッセージを待つことです。


0

非組み込みシステムの場合、C#で行っていたことはSCADAシステムでした。ロードがシステム生成イベントの一部をアンロードし、他の部分がデータベースに新しい状態を書き込んでいたときにウェアハウスで起こっていたことに関連する多くのイベントがありました。もちろん、GUIクライアントはいくつかありましたが、倉庫の状態を反映しているデータベースの状態を表示するだけでした。そのため、イベントとスレッドに基づくバックエンドサーバーソフトウェアでした。開発するのはかなり難しい。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.