wake-up-neo.com

Data Pull vs. Push OOP Ansatz

Wenn ich mein System von Grund auf neu entwerfe, stehe ich oft vor einem Dilemma, ob mein Objekt Push Informationen in andere Objekte OR einfügen soll, ob die Objekte pull die erforderlichen Daten von anderen Objekten _ _ sollen .

Gibt es so etwas wie einen Standard im OOP - Design, dass ich das Ziehen von Daten gegenüber Objekten vorziehen sollte, anstatt Daten in Objekte zu verschieben? 

Kann jemand erfahren, ob ein Ansatz aus längerfristiger Sicht besser ist als der andere, oder wenn die Struktur/Rahmen/Diagramm OOP komplexer wird?

38
Bunkai.Satori

Laut tell nicht fragen , Push ist besser - oder mehr OO. Sie möchten das Objekt nicht nach Daten abfragen, damit Sie etwas tun können. Sie möchten, dass das Objekt dies tut, weil er derjenige ist, der seine Daten kennt.

Zugehöriger Artikel über böse Getter

23
Kamil Tomšík

Wie bereits in anderen Antworten erwähnt, ist weder Push noch Pull besser, sondern Sie sollten sich dasjenige aussuchen, das am besten zu Ihren Designanforderungen passt.

Von hier Diskutieren, ob ein Beobachtermodell Push oder Pull sein soll:

Wer löst das Update aus?

Die Kommunikation zwischen dem Subjekt und seinen Beobachtern ist abgeschlossen über die Benachrichtigungsmethode, die in der Observer-Schnittstelle deklariert ist. Aber es kann von einem Subjekt oder einem Beobachterobjekt ausgelöst werden. Normalerweise die Die Benachrichtigungsmethode wird vom Betreff ausgelöst, wenn der Status geändert wird . Aber wenn die Updates häufig sind, werden die aufeinanderfolgenden Änderungen in Der Betreff bestimmt viele unnötige Aktualisierungsvorgänge in der Beobachter. Um diesen Vorgang effizienter zu gestalten, muss der Beobachter kann für den Start der Benachrichtigungsoperation verantwortlich gemacht werden, wenn sie als notwendig erachten.

Für dieses Muster ist die bestimmende Eigenschaft die Häufigkeit, mit der sich die Daten ändern, und dann die entsprechende Rate, mit der die Beobachter diese Daten empfangen möchten. Wenn die Beobachter wünschen, dass die Daten langsamer sind, als das Subjekt die Daten generiert (ein Beispiel wäre GPS auf einem Telefon, Sie brauchen nicht ständig Ihre Position, nur wenn Sie eine bestimmte Verwendung dafür haben) effizienter. Wenn die Beobachter die Daten so schnell haben möchten, wie das Subjekt sie produzieren kann (ein mögliches Beispiel wäre eine Echtzeit-Börsenticker-Anwendung), sind Push-Benachrichtigungen wahrscheinlich besser.

20
mydogisbox

Ich denke, dass die Diskussion hier den entscheidenden Punkt beim Ziehen und Schieben verpasst und an einzelnen Beispielen und Fällen feststeckt.

Pushing: Der Vorteil des Pushens ist, dass Sie Ihre Daten kennen und wissen, was Sie tun. Keine Komponente kennt (oder sollte nicht wissen) die Daten besser als die Komponente, der die Daten gehören, was theoretisch ein besseres Design und ein robusteres System impliziert.

Ziehen : Der einzige Vorteil, den ich beim Ziehen sehe, ist die Komponente, die genau weiß, wann sie ziehen soll. Es kann die Konversation initiieren, wenn die Daten benötigt werden und keine Komponente weiß (oder nicht wissen sollte), wann die Daten benötigt werden, als die Komponente, die sie benötigt.

Meine Schlussfolgerung dazu lautet: Unabhängig davon, welche Komponente die Transaktion besitzt, leitet sie die Transaktion ein . Wenn Sie Daten von einer API abrufen, ist der API-Client natürlich Eigentümer der Transaktion und führt einen Pull aus. Wenn Sie eine Nachricht übertragen, besitzt der Sender die Transaktion, so dass ein Push ausgeführt wird. 

18
ralzaul

In OOP sollte es nicht anders sein (es gibt etwas, das ich vermisst habe), aber ein Pull-Ansatz ist besser.

Der Grund, warum ich dies sage, ist auf die jüngsten Trends bei Designmustern zurückzuführen. Domain Driven Design und CQRS Da sie einige der prominentesten sind, fördern sie die lose Kopplung, was eine sehr gute Sache ist.

Ein Objekt sollte sich nicht darum kümmern, was ein anderes Objekt mit seinen Daten macht, es liegt also nicht in seiner Verantwortung. Das Objekt sollte nur die Daten verfügbar machen, und die Daten, die die Daten benötigen, sollten sie abrufen bzw. von diesem Objekt abrufen. Sehen Sie sich das ereignisgesteuerte Design an.

Es macht das Objekt unabhängig von den anderen Objekten und macht es portabler (muss nicht ändern, wohin es drückt, da es von dort gezogen wird).

TL; DR Ich würde es empfehlen, überzuziehen.

HINWEIS: Alle diese verschiedenen Designmuster schließen sich nicht aus, sondern koexistieren.

3
Tehnix

ziel. Drücken Sie (Quelle)

  • Destination weiß, was und wie Daten von Source bezogen werden
  • Das Ziel muss von der Quelle abhängen, oder
  • else muss eine bereitgestellte ISource-Schnittstelle implementieren und ist vom Anbieter abhängig (möglicherweise das Destination-Paket).
  • Die Methode hat direkten privaten Zugriff auf Destination.

source. Pull (Ziel)

  • Quelle weiß, was und wie man sie anlegt
  • Quelle muss vom Ziel abhängen, oder
  • else Destination muss eine bereitgestellte IDestination-Schnittstelle implementieren und ist vom Anbieter abhängig (möglicherweise Quellpaket).
  • Die Methode hat direkten privaten Zugriff auf Source.

Wählen Sie Ihre Lösung aus, indem Sie die Abhängigkeiten betrachten, die Sie in Ihrem Code haben möchten.

Wenn Quelle und Ziel nicht davon abhängen können, was für das vorherige Schema erforderlich ist, muss die Aktion von einer externen Methode ausgeführt werden, die sowohl Quelle als auch Ziel kennt (abhängig von). Es hat jedoch nur öffentlichen Zugang zu beiden.

Wenn Sie eine virtuelle ISource benötigen, um eine IDestination zu speisen, benötigen Sie diese Schnittstellen, um alle Methoden bereitzustellen, die für eine externe Methode zum Ausführen der Aktion erforderlich sind.

Wenn eine einzelne externe Methode die Aktion nicht für eine ISource und keine IDestination ausführen kann, möchten Sie das Besuchermuster, die Besucherklasse, die alle bestimmten Aktionen für Source1 und SourceX Destination1 und DestinationY ausführt.

2
franckspike

Das Word Push/Pull ist relativ. Es wird einen Schieber geben, der über Daten verfügt, und es wird einen Puller geben, der Daten benötigt. Wenn wir die Daten tatsächlich an einem neutralen Ort und nicht in Push-er/Puller speichern, eröffnen sich viele Möglichkeiten, die zu einem gegebenen Problem zu einem bestimmten Zeitpunkt passen. Einer aktualisiert die Daten, wenn er sie hat (wenn nötig, Benachrichtigung senden) und die anderen ziehen Die Daten stehen zu seiner Bequemlichkeit zur Verfügung. Viele Designmuster, MVC, Observer, Command usw. passen in das Szenario.

1
Senthil

Die Antwort hängt von Ihren Architekturzielen ab, dh es gibt keine allgemeine Lösung.

In einer Client-Server-Architektur haben Sie wahrscheinlich ein geschichtetes System im Backend, in dem Objekte den Status von anderen Objekten ziehen. Das heißt, nur bestimmte "Dienste" aktualisieren am Ende den Zustand eines Objekts. Beispiel: Erstellen eines neuen Objekts, Aktualisieren eines Felds eines Objekts usw. (z. B. Hinzufügen eines neuen Bestellpostens zum Gesamtauftrag).

In der monolithischen Desktop-Anwendung kann es völlig anders sein. Sie verwenden wahrscheinlich "Model-View-Controller" -Variationen und Beobachtermuster usw. In diesem Fall drücken Sie info, z. zur Benutzeroberfläche.

1
Angel O'Sphere

In der Regel bedeutet "Daten ziehen", dass Sie einen Ajax-Anruf tätigen und bei erfolgreicher Antwort einen Rückruf ausführen. Das ist nicht schlecht, aber es kann zu intensiv sein, wenn Sie nach Datenaktualisierungen suchen und dies daher in einem Intervall tun.

Eine Alternative dazu im Kontext einer Online-Webanwendung ist Push mit langer Abfrage. Da lange Abfragen sich nicht sehr von der ersten Methode unterscheiden, schlage ich vor, dass Sie Folgendes tun:

Erstellen Sie eine lange Abfragemethode, die Daten von einem halböffentlichen Push-URL-Endpunkt (auch als Webservice für Pubsub bezeichnet) abruft, und aktualisieren Sie dann alles, was mithilfe eines Publisher-Subscriber-Entwurfsmusters in Ihrem Client aktualisiert werden muss. Auf diese Weise sind Ihre Aktualisierungen stärker von der Datenquelle entkoppelt.

Hier ist ein Whitepaper, das von IBM zu diesem Thema geschrieben wurde. http://www.ibm.com/developerworks/library/specification/ws-pubsub/

1
Kristian

Erstens lautet die allgemeine Richtlinie eindeutig: Objekte sind data und Verhalten. Dies fördert weniger Getter und somit weniger Pulls, indem Methoden bereitgestellt werden, die do etwas mit den internen Daten angeben.

Allein "Push ist besser" (in der akzeptierten Antwort) kann nicht ganz funktionieren, da eine Push-Operation in einigen Klassen einen neuen Pull am geschobenen Objekt erfordern kann. Stattdessen sollten Sie die Push-Operation dort hinzufügen, wo sie am besten zur Abstraktion passt. Dies kann sogar zu einer neuen, abstrakteren Klasse/Zusammensetzung führen (siehe Objektorientierte Designheuristik , Riel, 1996, S. 37 f.).

1
sevenforce

Aus meiner Sicht ... Als Desktop-Anwendungsentwickler, der mvc verwendet, gibt es eine heikle Balance, bei der durch Push von Daten, wenn sie für Modellobjekte verfügbar sind, die Daten dann auf der Logik des Modells (Zeitgeber/asynchrone Ereignisse/Benachrichtigungen) basieren Zu den Controllern und umgekehrt zur Ansicht gedrückt ... Die UI-Interaktionen können je nach Präferenz beliebig sein, sie können eine Aktualisierungs- oder Aktualisierungsnachricht auslösen, die dem Controller mitteilt, dass er etwas tun muss, oder er kann Daten gezielt hineinpushen der Controller und oftmals das Modell.

Natürlich wird dies durch Szenarien aus der realen Welt vereinfacht und durcheinander gebracht, aber wenn man genug Mittel hat, um einen bestimmten Weg zu gehen, kann das einen großen Weg gehen.

0
Grady Player