タグ付けされた質問 「observer-pattern」

1
Consumer / ProducerとObserver / Observableの違い
私は、次の3つの部分で構成されるアプリケーションの設計に取り組んでいます。 特定のイベントの発生(ファイルの作成、外部リクエストなど)を監視する単一のスレッド これらのイベントを処理することでこれらのイベントに応答するN個のワーカースレッド(各ワーカーは単一のイベントを処理して消費し、処理に時間がかかる場合があります) これらのスレッドを管理し、エラー処理を行うコントローラー(スレッドの再起動、結果のログ記録) これは非常に基本的で実装するのは難しくありませんが、それを行うための「正しい」方法は何だろうと思っています(この具体的なケースではJavaですが、より高い抽象化の答えもありがたいです)。2つの戦略が思い浮かびます。 Observer / Observable:監視スレッドはコントローラーによって監視されます。イベントが発生した場合、コントローラーに通知され、再利用可能なキャッシュスレッドプールから新しいタスクを空きスレッドに割り当てることができます(または、すべてのスレッドが現在ビジーである場合、FIFOキューでタスクを待機してキャッシュします)。ワーカースレッドはCallableを実装し、結果(またはブール値)で成功を返すか、エラーを返します。その場合、コントローラーは何をすべきかを決定します(発生したエラーの性質に応じて)。 プロデューサー/コンシューマー:監視スレッドはコントローラーとBlockingQueueを共有し(イベントキュー)、コントローラーはすべてのワーカーと2つを共有します(タスクキューと結果キュー)。イベントの場合、監視スレッドはタスクオブジェクトをイベントキューに入れます。コントローラーは、イベントキューから新しいタスクを取得し、それらをレビューして、タスクキューに入れます。各ワーカーは新しいタスクを待機し、タスクキュー(先着順、キュー自体で管理)からそれらを取得/消費し、結果またはエラーを結果キューに戻します。最後に、コントローラーは結果キューから結果を取得し、エラーが発生した場合に対応する手順を実行できます。 両方のアプローチの最終結果は似ていますが、それぞれわずかな違いがあります。 オブザーバーを使用すると、スレッドの制御は直接行われ、各タスクは特定の新しく生成されたワーカーに割り当てられます。スレッド作成のオーバーヘッドは高くなる可能性がありますが、キャッシュされたスレッドプールのおかげではありません。一方、Observerパターンは、複数ではなく単一のObserverに縮小されます。これは、厳密に設計されたものではありません。 キュー戦略は拡張が容易なようです。たとえば、1つではなく複数のプロデューサーを追加するのは簡単で、変更を必要としません。欠点は、作業をまったく行わない場合でも、すべてのスレッドが無期限に実行され、エラー/結果の処理が最初のソリューションほど洗練されていないことです。 この状況で最もふさわしいアプローチは何ですか?その理由は?ほとんどの例は、Observerケースの新しい値で多くのウィンドウを更新したり、複数のコンシューマーとプロデューサーで処理したりするなど、明確なケースのみを扱っているため、この質問に対する答えをオンラインで見つけるのは難しいと感じました。どんな入力でも大歓迎です。

4
ロギングに適した設計パターンはどれですか?
プログラム内のいくつかのイベントをログに記録する必要がありますが、プログラムの実際の機能に関するものではないため、ログコードをプログラムの外部に置いた方がよいでしょう。それで、コードから完全に除外し、オブザーバーとリスナーのみを使用してイベントをログに記録する必要があるかどうかを教えてもらえますか?または、何かをログに記録する必要がある場合はいつでも、次のようなコード行を追加できます。 MyGloriousLogger.getXXXLogger().Log(LogPlace, new LogObject(z1, z2, z3, z4, ..., z99)); Observer設計パターンを使用するのは間違いですか?別のデザインパターンが必要ですか?または私はデザインパターンについて考えるのをやめるべきですか? PS1。リスナーとオブザーバーのみを使用してログを記録したい場合は、プログラムのオブザーバーとリスナーを追加して改善する必要があります。 PS2。Javaにログインするためのさまざまなライブラリがあり、java.utils.loggingを使用していることは確かですが、特別なオブジェクトをログに記録するためのラッパーが必要です。

3
オブザーバーパターン。何が変わったのか知っていますか?
古典的なObserverパターンインターフェイスを定義する2つの抽象クラスSubjectとObserverを作成しました。オブザーバーパターンを実装するためにそれらから派生しています。オブザーバーは次のようになります。 void MyClass::Update(Subject *subject) { if(subject == myService_) { DoSomething(); } else if(subject == myOtherService_) { DoSomethingElse(); } } これは問題なく、誰が何かを変更したかがわかります。ただし、何が変わったのかはわかりません。サブジェクトに最新のデータを照会するだけでよい場合もありますが、サブジェクトで何が変更されたかを正確に知る必要がある場合もあります。Javaでは、おそらく何が変更されたかの詳細を指定するために、notifyObservers()メソッドとnotifyObservers(Object arg)メソッドの両方があることに気づきました。 私の場合、サブジェクトでいくつかの異なるアクションの1つが発生したかどうかを知り、それが特定のアクションである場合は、そのアクションに関連する整数を知る必要があります。 だから私の質問は: (Javaのように)汎用的な引数を渡すC ++の方法は何ですか? オブザーバーは最高のパターンですか?多分ある種のイベントシステム? 更新 Observerパターンのテンプレート化について説明しているこの記事を見つけました:テンプレートを使用したSubject / Observerパターンの実装。これは、あなたが議論をテンプレート化できるかどうか疑問に思いました。 引数のテンプレート化に関するこのスタックオーバーフローの質問が見つかりました:テンプレートベースのサブジェクトオブザーバーパターン-static_castまたはdynamic_castを使用する必要があります。しかし、OPには誰も答えていない問題があるようです。 もう1つの方法は、Updateメソッドを変更して、次のようにEventArgオブジェクトを取得することです。 void MyClass::Update(Subject *subject, EventArg arg) { ... 次に、特定の引数データ用にEventArgのサブクラスを作成し、それをupdateメソッド内の特定のサブクラスにキャストし直したと思います。 アップデート2 また、非同期メッセージベースのc ++フレームワークの作成に関する記事も見つかりました。何が変わったかについての詳細を被験者に伝えることを論じるパート2 Boost.Signalsの使用を真剣に検討しています。自分のオブザーバーパターンを使用することは、それが単純な場合には理にかなっていますが、型と引数のテンプレート化は複雑になり始めています。そして、Boost.Signals2のスレッドセーフが必要になる場合があります。 アップデート3 オブザーバーパターンに関する興味深い記事もいくつか見つかりました。 ハーブサッターによるオブザーバーの一般化 C ++でのオブザーバーパターンの実装-パート1 Observerデザインパターンの実装の経験(パート2) …

1
プルメカニズムを使用したオブザーバーパターン
以下の実装について疑問に思っていました public void update(Observable obs, Object arg) 私はすべてのオブザーバーに送信し、notifyObserver()Iを使用して更新しthis、オブザーバーに参照を渡すとgetters、サブジェクトのを使用して、必要な情報をプルできます。 argupdateメソッドの引数は何のためのものですか?

2
オブザーバーパターンは、オブザーバーが互いに独立していない場合に適していますか?
私class Carは2つのプロパティを持つを持っています:int priceとboolean inStock。またList、abstract class State(空のクラス)も保持します。車に適用できる2つの状態があり、それぞれが独自のクラスで表されます:class Upgrade extends Stateおよびclass Shipping extends State。 A Carは、2つの状態をそれぞれいくつでも保持できます。州には次の規則があります。 Upgrade:1自動車自体に適用される各状態の価格に追加されます。 Shipping:Shippingリストに少なくとも1つの状態がある場合、inStockに設定されfalseます。 たとえば、始まるprice = 1とinStock = true: add Shipping s1 --> price: 1, inStock: false add Upgrade g1 --> price: 1, inStock: false add Shipping s2 --> price: 2, inStock: false add Shipping s3 --> price: …

4
.NETのIObserver <T>は、複数のIObservableをサブスクライブすることを目的としていましたか?
.NETにはIObservableおよびIObserverインターフェイスがあります(こことここも)。興味深いことに、IObserverの具体的な実装は、IObservableへの直接参照を保持していません。誰が購読しているかはわかりません。購読解除者のみを呼び出すことができます。「登録を解除するにはピンを抜いてください。」 編集:購読解除者はを実装しIDisposableます。この方式は、リスナーの失効問題を防ぐために使用されたと思います。 しかし、2つのことは完全に明確ではありません。 内部のUnsubscriberクラスはsubscribe-and-forget動作を提供しますか?誰が(正確にはいつ)登録IDisposable.Dispose()解除者を呼び出すのですか?ガベージコレクター(GC)は確定的ではありません。 [免責事項:全体として、私はC#よりもCおよびC ++に多くの時間を費やしました。] オブザーバーKをオブザーバブルL1にサブスクライブし、オブザーバーが他のオブザーバブルL2にすでにサブスクライブしている場合はどうなりますか? K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004); このテストコードをMSDNの例に対して実行したとき、オブザーバーはL1にサブスクライブしたままでした。これは実際の開発に特有のものです。潜在的に、これを改善する3つの方法があります。 オブザーバーがすでにサブスクライブ解除インスタンスを持っている(つまり、すでにサブスクライブしている)場合、オブザーバーは新しいプロバイダーにサブスクライブする前に、元のプロバイダーから静かにサブスクライブ解除します。このアプローチにより、元のプロバイダーにサブスクライブされなくなったという事実が隠されます。これは、後で驚くかもしれません。 オブザーバーがすでにサブスクライブ解除インスタンスを持っている場合は、例外がスローされます。正常に動作する呼び出しコードは、オブザーバーを明示的にサブスクライブ解除する必要があります。 オブザーバーは複数のプロバイダーにサブスクライブします。これは最も興味深いオプションですが、IObservableとIObserverで実装できますか?どれどれ。オブザーバがサブスクライバオブジェクトのリストを保持することは可能です:ソースごとに1つ。残念ながら、IObserver.OnComplete()それを送信したプロバイダーに戻って参照を提供していません。したがって、複数のプロバイダーを使用するIObserver実装は、どのプロバイダーからサブスクライブを解除するかを決定できません。 .NETのIObserverは、複数のIObservableをサブスクライブすることを目的としていましたか? テキスト形式のオブザーバーパターンの定義では、1人のオブザーバーが複数のプロバイダーにサブスクライブできる必要があるか?それともオプションで実装に依存していますか?

5
オブザーバーパターンに対するデリゲートパターンの利点は何ですか?
でデリゲートパターン、1つのオブジェクトのみが直接、別のオブジェクトのイベントに耳を傾けることができます。でオブザーバーパターン、オブジェクトの任意の数は、特定のオブジェクトのイベントに耳を傾けることができます。他のオブジェクトにイベントを通知する必要があるクラスを設計するときに、オブザーバーパターンよりもデリゲートパターンを使用するのはなぜですか?オブザーバーパターンはより柔軟であると思います。現在、オブザーバーは1人しかいませんが、将来の設計では複数のオブザーバーが必要になる場合があります。

2
HTTPおよびTCP / IPを介したオブザーバーパターン(サーバークライアント)
私はサーバーと多くのクライアント(約50クライアント)がWebアプリケーションに基づいてそのサーバーに接続するクライアントを持っています。これはもちろん、HTTPプロトコルに基づいており、TCP / IPを使用しています(間違っている場合は修正してください。ネットワーキングは本当に得意ではありません)。 問題は、私が警告メカニズムを開発する必要があることです。誰かが危険な値を含むフォームを送信すると、マネージャー(同じWebアプリケーションを介して接続されている)が彼の画面に警告ポップアップを受信します。 -time(瞬時に)。 ただし、HTTPプロトコルはステートレスなので、ここでは少し戸惑います。これを実装する方法がわかりません。 ソリューションの1つは、JavaScriptをsetInterval()関数と一緒に使用して、サーバーから毎秒データをプルすることです。しかし、これは私には少し汚く、専門家ではないようです。 別のソリューションを実装するアイデアはありますか?
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.