イベントはGUIプログラミングにのみ使用されますか?
他の何かに何かが起こった場合、通常のバックエンドプログラミングではどのように処理しますか?
イベントはGUIプログラミングにのみ使用されますか?
他の何かに何かが起こった場合、通常のバックエンドプログラミングではどのように処理しますか?
回答:
いや。それらは、オブザーバーを実装し、クラスが変更されないようにするのに本当に便利です。
新しいユーザーを登録するメソッドがあるとします。
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つは、クラスが互いにメッセージを送信することです。イベントはこれらのメッセージです。
いや。
非GUIロジックで使用されるイベントの典型的な例は、データベーストリガーです。
トリガーは、特定のイベント(INSERT、DELETEなど)が発生したときに実行されるコードです。私にとってはイベントのようです。
これはイベントのウィキペディア定義です:
コンピューティングにおいて、イベントとは、ソフトウェアによって処理される可能性のあるソフトウェアによって認識されるアクションまたは発生です。コンピューターイベントは、システム、ユーザー、またはその他の方法で生成またはトリガーできます。通常、イベントはプログラムフローと同期して処理されます。つまり、ソフトウェアには、イベントが処理される1つ以上の専用の場所(多くの場合、イベントループ)があります。イベントのソースには、ユーザーが含まれます。ユーザーは、たとえば、キーボードのキーストロークによってソフトウェアと対話できます。別のソースは、タイマーなどのハードウェアデバイスです。ソフトウェアは、たとえばタスクの完了を伝えるために、イベントループに独自のイベントセットをトリガーすることもできます。イベントに応答して動作を変更するソフトウェアは、多くの場合、インタラクティブであることを目的として、イベント駆動型と言われています。
すべてのイベントがユーザー生成されるわけではありません。前述のように、一部はcrontabのようなタイマーによって、またはデータベースINSERTによって生成されます。
定義では、一部のプログラムまたはシステムは「イベント駆動型であり、多くの場合、インタラクティブであることを目標としている」と述べており、イベントの目的または有用性は、単に対話ではなく、GUI必ずしもGUIではありませんが、CLIプログラムも対話型である可能性があります)。
実際、イベントベースのプログラミングは、パフォーマンスの高いサーバープログラミングにも使用されます。
通常のサーバーワークロードでは、結果の処理のほとんどの時間は実際にはI / Oから来ます。たとえば、(7200 RPM)ハードディスクドライブからデータを引き出すには、最大8.3 msかかります。最新のGHzプロセッサの場合、これは100万クロックサイクルに相当します。CPUが毎回データを待機する(何もしない)場合、クロックサイクルの多くが失われます。
従来のプログラミング手法では、複数のスレッドを導入することでこれを回避しています。CPUは数百のスレッドを同時に実行しようとします。ただし、このモデルの問題は、CPUがスレッドを切り替えるたびに、コンテキストの切り替えに数百のクロックサイクルが必要になることです。コンテキストスイッチは、CPUがスレッドローカルメモリをCPUのレジスターにコピーし、古いスレッドのレジスター/状態をRAMに保存する場合です。
さらに、各スレッドは、その状態を保存するために一定量のメモリを使い果たす必要があります。
今日、単一のスレッドを持ち、ループで実行されるサーバーのプッシュが行われています。次に、作業がメッセージポンプにプッシュされます。メッセージポンプは、単一のスレッドのキューとして機能します(UIスレッドのように)。CPUは、作業が完了するのを待つ代わりに、ハードディスクドライブへのアクセスなどのコールバックイベントを設定します。コンテキストの切り替えが減少します。
そのようなサーバーの最良の例はNode.jsです。これは、控えめなハードウェアで100万の同時接続を処理できることが示されていますが、Java / Tomcatサーバーは数千で苦労します。
イベントはネットワークプログラミング(Nginxなど)でも頻繁に使用され、高価なビジー待機ループを回避し、代わりに特定の操作(I / O、緊急データなど)がいつ利用可能かを正確に知るためのクリーンなインターフェイスを提供します。これはC10k問題の解決策でもあります。
基本的な考え方は、イベント、すべてのイベント、または特に関心のあるイベント(たとえば、読み取り可能なデータ)を監視するためのソケットセット(ネットワーク接続)をOSに提供することです。このようなアクティビティがリスト内のソケットの1つでオペレーティングシステムによって検出されると、APIが探していたイベントの通知を取得します。次に、それがどこから来たかを整理し、それに応じて行動する必要があります。
さて、これは低レベルで抽象的なビューであり、さらに拡張性を高めるのはさらに困難です。しかし、さらにクロスプラットフォームの方法でそれを処理する多くの高レベルのフレームワークがあります。PythonではTwisted、C ++ではBoost.Asio、Cではlibeventが思い浮かびます。
組み込みシステムは、明示的にプログラムされていない場合でも、ほとんど常に本質的にイベント駆動型です。
これらのイベントは、ハードウェア割り込み、ボタンの押下、アナログからデジタルへの定期的な読み取り、タイマーの期限切れなどのようなものから発生します。
低電力の組み込みシステムは、イベント駆動型である可能性がさらに高くなります。彼らはほとんどの時間をスリープ(CPUは低電力モードでスリープ)して、何かが起こるのを待っています(「何か」はイベントです)。
イベント駆動型組み込みシステムの最も一般的で人気のあるフレームワークの1つは、Quantum Platform(QP)です(QPはLinux、Windows、およびUnix系OSでも動作します)。ステートマシンは、イベント駆動型プログラミングに最適です。プログラムは典型的な意味で「シーケンシャル」ではなく、むしろ、システム状態と現在のイベントに応じて呼び出される「コールバック」のセットです。
イベントメッセージ Gregor Hohpe。
イベント駆動型アーキテクチャ Gregor Hohpe。
SEDAアーキテクチャ、ウェールズ、カラー、ブリューワー。
通常のバックエンドプログラミングでは、何か他のことが起こった場合、どのように対処しますか?
有限状態機械は、1つの一般的なアプローチです
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
組み込みシステムでは、割り込み中にイベントが発生します。タイマーからI / Oまで、多くの割り込みソースがあります。
また、RTOSはイベントも持つことができます。1つの例は、別のタスクからのメッセージを待つことです。
非組み込みシステムの場合、C#で行っていたことはSCADAシステムでした。ロードがシステム生成イベントの一部をアンロードし、他の部分がデータベースに新しい状態を書き込んでいたときにウェアハウスで起こっていたことに関連する多くのイベントがありました。もちろん、GUIクライアントはいくつかありましたが、倉庫の状態を反映しているデータベースの状態を表示するだけでした。そのため、イベントとスレッドに基づくバックエンドサーバーソフトウェアでした。開発するのはかなり難しい。