パブリッシュ/サブスクライブパターンは、gotoとどのように異なりますか?


11

私の理解では、後藤声明は一般的に眉をひそめているということです。しかし、パブリッシュ/サブスクライブパターンは、コードの一部がメッセージをパブリッシュすると、一方向の制御の転送を実行するという点で概念的に類似しているようです。プログラマは、プログラムのどの部分がこのメッセージにサブスクライブしているかわからない場合があります。

イベントを使用してモジュール間を便利に「ホップ」するJavaScriptプログラムの多くで、似たようなものを見てきました。パブリッシュ/サブスクライブまたはイベント駆動型のパターンについて何かが欠けていますか?


5
returntry/catchbreakcontinueswitch-それらはすべて goto。後藤に建てられた制限のさまざまなレベルでの有害がどのようにコードの動作についての考え方に有害であると考えました。

@MichaelT:圧倒的多数のケースでは、gotoに代わるものがあり、コードについて推論しやすくなります。その事実を認めても害はありません。正当な場合にgotoを使用しない場合(通常はそうではありません)、またはgotoを不注意に使用する場合にのみ、害が発生します。Apple は後者の良い例を示したと思う。
back2dos 14年

...プログラムのどの部分がサブスクライブしているのかわかりません...:最初の大きな違いgotoは、パートの最後のsにあります。2番目の大きな違いは、何も考えていないことにあります。3番目の大きな違いはそれが概念的にa gosubであることですgoto
ムービシエル14年

1
それはINTERCALの「来た」に近い。
CodesInChaos 14年

@ back2dosは、1行のコードブロックであっても中括弧を使用することを好む理由の良い例でもあります。
メタファイト14年

回答:


19

うん、あなたは間違いなく何かを逃しています。あなたが言ったように、Gotosは通常、一方通行の制御を実行するために使用されます。

ただし、イベントはそれを行いません。コードがイベントを起動すると、イベントが発行(または処理、キューイング、起動など)されると、イベントを生成したコードの次の行でコードの実行が再開されることを十分に認識しています。

gotoを使用すると、そのステートメントを呼び出すコードと受信側のコードが非常に密に結合されます。開発者がgotoを使用するには、両方の場所に関する詳細な知識が必要です。

一方、イベントを発生させるコードは、通常、そのイベントをリッスンすることに興味がある人を知りませんし、気にしません。リスナーがいる可能性があります。または、100人または0人のリスナーが存在する可能性があります。これらのリスナーは、イベントが発生した同じプログラムに存在するか、まったく異なるアプリケーションに存在するか、異なるマシンに存在する可能性があります。出版社に関する限り、イベントを生成するとすぐに仕事が完了します。

これまでに私と一緒にいる場合、上記で説明したのは、pub / subパターンの理想的なケースです。残念ながら、現実の世界では物事は必ずしも理想的ではなく、パブリッシャーがイベントを生成し、サブスクライバーが呼び出され、状態の束全体を変更し、コード実行がパブリッシャーに戻るまでに「世界」が持っているように見える場合があります逆さまにされました。この状況は、pub / subパターンが非常に単純な方法で実装されている場合にしばしば発生するため(たとえば、C#のデリゲートまたはイベント、またはCの関数/インターフェイスポインターを使用して) / C ++)。

しかし、この問題は必ずしもpub / subパターンではなく、むしろその実装です。これが、多くのシステムがキューに依存しているため、イベントが発行されると、イベントがキューイングされて後で呼び出されるだけで、パブリッシャーは世界がまだ損なわれていない間に実行を終了することができます。パブリッシャーが作業を完了すると、イベントループ(ディスパッチループとも呼ばれます)がイベントをポップし、サブスクライバーを呼び出します。


+1パブリッシュ/サブスクライブにより、疎結合が可能になります。後藤はない
Fuhrmanator

6

いくつかの違いがあります。まず、コードがGOTOを実行すると、制御を放棄し、制御を取り戻す保証はありません。ただし、pub / subのパブリッシャーは、ロジックを実行および実行し続け、必要に応じてメッセージを送信します。その動作は理解可能であり、予測可能です。

次に、サブスクライバーはメッセージを受信します。GOTOとは異なり、メッセージ自体にコンテキストが含まれます。メッセージのタイプと、それが伝えるプロパティの両方が、サブスクライバーにその役割を実行することを伝えるのに役立ちます。また、メッセージを処理した後も、サブスクライバーは新しいメッセージを取得できます。そのため、その動作も理解可能で予測可能です。

大きな違いは、パブリッシャーとサブスクライバーには明確に定義された実行フローがあり、メッセージを送受信している間、本質的にループとジョブの実行を続けるということです。GOTOを使用したコードは、適切に作成され、整然としている場合がありますが、品質が低下する可能性もあり、明確に理解された動作を保証するものではありません。

しかし、あなたは正しい。誰もが非常に多くのメッセージと非常に多くの小さなジャンプでパブ/サブシステムを書くことができたので、処理フローを追跡することは悪夢になる可能性がありました。一方、GOTOを使用して非常に規則正しく動作し、理解しやすいシステムを作成することもできます。(シンボリック言語が引き継ぐ前に、非常に複雑なシステムのアセンブリコードを考えています。)

しかし、通常、pub / subから得られる分離は、分散処理の問題を単純化し、システム内のロジックを分離します。また、通常、ストレートGOTOは、制御の流れを理解することが問題になる複雑なシステムを作成する傾向があります。

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