web-dev-qa-db-ja.com

データのプルとプッシュの比較OOPアプローチ

システムを最初から設計するとき、オブジェクトがPush別のオブジェクトに情報を提供するかどうかORオブジェクトを使用する必要があるかどうかpull =別のオブジェクトからの必要なデータ。

OOPデザインの標準のようなものはありますか、オブジェクトへのデータのプッシュよりもオブジェクトによるデータのプルを優先する必要がありますか?

長期的な観点の観点から、またはOOP構造/ framework/diagramはより複雑になりますか?

40
Bunkai.Satori

tell dont ask によると、Push is better-以上のOO。オブジェクトにデータのクエリを実行したくないので、何かを行うことができます。データを知っているのは彼だからです。

邪悪なゲッターに関する関連記事

25
Kamil Tomšík

ここでの議論は、プルとプッシュに関する重要なポイントが欠けているようなものであり、個々の例やケースに固執しています。

Pushing:プッシュの利点は、データを理解していて、何をプッシュしているのかを知っていることです。データを所有しているコンポーネントよりもデータをよく知っている(または知らない)コンポーネントはありません。これは、理論的には、より優れた設計とより堅牢なシステムを意味します。

Pulling:プルアプローチで見られる唯一の利点は、プルするコンポーネントが、プルするタイミングを正確に把握していることです。データが必要で、コンポーネントがデータを必要とするコンポーネントよりもデータが必要な場合を知らない(または知らない)場合に、会話を開始できます。

それに関する私の結論は次のとおりです:コンポーネントがトランザクションを所有している場合は、トランザクションを開始します。 APIからデータを取得する場合、明らかにAPIクライアントがトランザクションを所有するため、プルを行います。メッセージをブロードキャストする場合、ブロードキャスターはトランザクションを所有しているため、プッシュを行います。

21
ralzaul

他の回答で述べたように、プッシュもプルも優れていませんが、デザインのニーズに最適なものを選択する必要があります。

here から、オブザーバーモデルをプッシュベースにするかプルベースにするかについて議論します。

誰が更新をトリガーしますか?

サブジェクトとそのオブザーバー間の通信は、オブザーバーインターフェイスで宣言された通知メソッドを介して行われます。ただし、サブジェクトまたはオブザーバーオブジェクトからトリガーできます。通常、通知メソッドは、状態が変更されたときにサブジェクトによってトリガーされます。ただし、更新が頻繁に行われる場合、サブジェクトの連続的な変更によって、オブザーバーでの多くの不要な更新操作が決定されることがあります。このプロセスをより効率的にするために、オブザーバーは、必要に応じて通知操作を開始する責任があります。

このパターンの場合、決定的な特性は、データが変化する頻度であり、観測者がそのデータの受信を希望する対応する速度です。オブザーバーが、対象がデータを生成するよりも遅い速度でデータを必要とする場合(例:電話のGPSの場合、常に位置を必要とせず、特定の用途がある場合のみ)、ポーリングはもっと効率的。オブザーバーがサブジェクトが生成するのと同じ速さでデータを必要とする場合(考えられる例は、リアルタイムの株式相場表示アプリケーションです)、プッシュ通知の方が良いでしょう。

20
N_A

OOP(私が見逃したものがあるかもしれません)で違いはないはずですが、プルアプローチの方が優れています。

これは、最近のデザインパターンの傾向によるものです。 ドメイン駆動設計[〜#〜] cqrs [〜#〜] は非常に目立つものの1つであり、疎結合を促進しますが、これは非常に良いことです。

オブジェクトは、別のオブジェクトがそのデータをどのように処理するかを気にする必要はありません。言うまでもありません。オブジェクトはデータを使用可能にするだけで、データを必要とするオブジェクトはそのオブジェクトからデータをフェッチ/プルする必要があります。イベント駆動型の設計を見てください。

これにより、オブジェクトが他のオブジェクトから独立し、移植性が向上します(プルされるため、プッシュ先を変更する必要はありません)。

TL; DRプッシュよりプルをお勧めします。

注:これらすべての異なる設計パターンは、相互に排除するのではなく、共存します。

4
Tehnix

宛先.プッシュ(ソース)

  • 宛先は、ソースからデータを取得する方法と方法を知っています。
  • 宛先はソースに依存する必要があります、または
  • そうでない場合、Sourceは提供されたISourceインターフェースを実装し、プロバイダーに依存する必要があります(Destinationパッケージである可能性があります)
  • メソッドには、宛先への直接プライベートアクセスがあります。

ソース.プル(宛先)

  • ソースは何をどのように宛先に入れるか知っています
  • ソースは宛先に依存する必要があります、または
  • そうでない場合、宛先は提供されたIDestinationインターフェースを実装し、プロバイダーに依存する必要があります(ソースパッケージの場合があります)。
  • このメソッドは、Sourceに直接プライベートアクセスできます。

コードに含める依存関係を確認して、ソリューションを選択します。

SourceとDestinationが前のスキームに必要なものに依存できない場合は、SourceとDestinationの両方を知っている(依存している)外部メソッドによってアクションを実行する必要があります。ただし、両方へのアクセスは公開されています。

IDestinationをフィードするために仮想ISourceが必要な場合は、外部メソッドがアクションを実行するために必要なすべてのメソッドを公開するためにそれらのインターフェースが必要です。

単一の外部メソッドがISourceおよびIDestinationでアクションを実行できない場合は、Visitorパターンを確認する必要があります。Visitorクラスは、特定のSource1およびSourceX Destination1およびDestinationYですべての特定のアクションを実行します。

2
franckspike

プッシュ/プルという言葉は相対的です。データを持っているプッシャーとデータを必要とするプーラーがあります。実際にデータをニュートラルな場所に保存し、Push-er/pull-erの内部ではない場合、特定の問題に適した多くの可能性が発生します。1人がデータを持っているときにデータを更新し(必要に応じて通知を送信)、もう1人はプルします彼の都合の良い時のデータ。多くのデザインパターン、MVC、オブザーバー、コマンドなどがシナリオを処理するために配置されます。

1
Senthil

答えはアーキテクチャの目標によって異なります。つまり、一般的な解決策はありません。

クライアントサーバーアーキテクチャでは、オブジェクトが他のオブジェクトから状態をプルするバックエンドに階層化システムがある可能性があります。つまり、特定の「サービス」だけが最終的にオブジェクトの状態を更新します。例:新しいオブジェクトの作成、オブジェクトのフィールドの更新など(新しい注文アイテムを注文全体に追加するように)。

モノリシックデスクトップアプリケーションでは、まったく異なる場合があります。 「Model-View-Controller」のバリエーションやオブザーバーパターンなどを使用している可能性があります。この場合、情報をプッシュします。 UIに。

1
Angel O'Sphere

通常、「データのプル」とは、ajax呼び出しを実行し、応答が成功したときにコールバックを実行していることを意味します。これは悪いことではありませんが、データの更新をチェックしているために間隔を置いて実行している場合は、過度に集中する可能性があります。

しかし、オンラインWebアプリケーションのコンテキストでは、これに代わるものとして、ロングポーリングを使用したプッシュがあります。ロングポーリングは最初の方法とそれほど変わらないので、以下を実行することをお勧めします。

セミパブリックプッシュURLエンドポイント(別名pubsubのWebサービス)からデータをプルする長いポーリングメソッドを作成し、クライアントでパブリッシャー/サブスクライバーデザインパターンを使用して更新する必要があるすべてを更新します。これにより、更新がデータソースからより分離されます。

これは、IBMがこのトピックについて書いたホワイトペーパーです。 http://www.ibm.com/developerworks/library/specification/ws-pubsub/

1
Kristian

まず、一般的なガイドラインは明確です:オブジェクトはdatabehaviorです。これにより、内部データを使用して何かをdoするメソッドを提供することで、getterを減らし、pullsを減らすことができます。

一部のクラスではプッシュ操作がプッシュされたオブジェクトで新しいプルを必要とする可能性があるため、「受け入れられた回答では」「プッシュの方が良い」だけでは十分に機能しません。代わりに、抽象化に最も適した場所にプッシュ操作を追加することをお勧めします。これにより、さらに抽象的なクラス/クラスの構成に至る可能性もあります( オブジェクト指向設計ヒューリスティックス 、Riel、1996、37ページを参照)。

1
sevenforce

私の観点から... mvcを使用するデスクトップアプリケーション開発者として、モデルオブジェクトで利用可能なときにデータをプッシュし、次にモデルのロジック(タイマー/非同期イベント/通知)に基づいてデータをプッシュする微妙なバランスがあります。コントローラーにプッシュされ、次にビューに... UIの相互作用は、設定に応じてどちらの方向にも進むことができます。コントローラーは、何かをする必要があることを通知する更新メッセージまたは更新メッセージを起動できます。コントローラ、そして多くの場合はモデルです。

もちろん、これは単純化されており、実際のシナリオでは混乱していますが、特定の方法で実行するための十分な準備ができていれば、長い道のりになる可能性があります。

0
Grady Player