Vermittler gegen Beobachter?

27

Kann mir jemand eine kanonische Antwort auf die Unterschiede zwischen a Observerund a geben Mediatorund eine Zusammenfassung darüber, wann Sie ein Muster über dem anderen verwenden sollten?

Ich bin mir nicht sicher, welche Art von Situation eine erfordern würde Observerund welche Art eine erfordern würdeMediator

Rachel
quelle
Ich möchte nach 7 Jahren Ihre eigene Idee dazu kennenlernen?
Niing

Antworten:

19

In dem ursprünglichen Buch, das die Begriffe Beobachter und Mediator, Entwurfsmuster und Elemente wiederverwendbarer objektorientierter Software geprägt hat, heißt es, dass das Mediatormuster unter Verwendung des Beobachtermusters implementiert werden kann. Es kann jedoch auch implementiert werden, indem Kollegen (die in etwa den Subjekten des Observer-Musters entsprechen) einen Verweis auf eine Mediator-Klasse oder eine Mediator-Schnittstelle haben.

Es gibt viele Fälle, in denen Sie das Beobachtermuster verwenden möchten. Der Schlüssel ist, dass ein Objekt nicht wissen sollte, welche anderen Objekte seinen Zustand beobachten.

Der Mediator ist etwas spezifischer, er vermeidet, dass die Klassen direkt kommunizieren, sondern über einen Mediator. Dies hilft dem Prinzip der Einzelverantwortung, indem die Kommunikation an eine Klasse ausgelagert werden kann, die sich nur darum kümmert.

Ein klassisches Mediator-Beispiel ist eine grafische Benutzeroberfläche, in der der naive Ansatz dazu führen kann, dass bei einem Schaltflächenklick-Ereignis der Code "Wenn das Foo-Bedienfeld deaktiviert ist und das Balkenbedienfeld die Bezeichnung" Bitte geben Sie das Datum ein "trägt, wird der Server nicht angerufen. Andernfalls weiter ", wo mit dem Mediator-Muster" Ich bin nur ein Knopf und habe keine irdischen Kenntnisse über das Foo-Bedienfeld und das Etikett auf dem Balkenbedienfeld, also frage ich einfach meinen Mediator, ob er den Server anruft ist jetzt in Ordnung. "

Oder, wenn es unter Verwendung des Beobachtermusters implementiert wird, würde die Schaltfläche sagen: "Hey, Beobachter (einschließlich des Vermittlers), mein Zustand hat sich geändert (jemand hat auf mich geklickt). Tun Sie etwas dagegen, wenn es Sie interessiert." In meinem Beispiel ist dies wahrscheinlich weniger sinnvoll, aber manchmal ist dies der Fall, und der Unterschied zwischen Observer und Mediator ist eher beabsichtigt als ein Unterschied im Code selbst.

bA
quelle
Vielen Dank, Ihre Beispiele haben mir wirklich geholfen, die Unterschiede zwischen den beiden zu verdeutlichen. Wenn ich Sie richtig verstehe, verwendet das Beobachtermuster ein Abonnement- / Broadcast-System von Nachrichten für die Kommunikation, während der Mediator einer global zugänglichen Entität gleicht, die Objekte nach Informationen abfragen können.
Rachel
@ Rachel - Ich würde den Beobachter so beschreiben wie Sie. Der Mediator ist wahrscheinlich nicht global, ist aber allen Objekten in der Gruppe bekannt, die miteinander kommuniziert hätten, aber jetzt den Mediator durchlaufen. Es sei denn, Mediator ist als Beobachter implementiert. In diesem Fall kennt er alle diese Objekte (zumindest über ihre beobachtbare Schnittstelle, möglicherweise direkt), aber sie wissen nichts darüber.
PSR
9

Die Beobachter - Muster funktionieren gut , wenn keine Koordination zwischen den Beobachtern notwendig ist , und das beobachtet Beziehung einen Weg geht.

Lassen Sie beispielsweise die Objekte B und C das Objekt A beobachten. Wenn das Objekt A das Ereignis X auslöst, sollte das Objekt B die Methode Y () und das Objekt C die Methode Z () ausführen. Wenn die Methoden BY () und CZ () völlig unabhängig sind und keine Koordination erfordern, verwenden Sie das Beobachtermuster.

Wenn BY () dagegen vor CZ () ausgeführt werden muss, möchten Sie das Mediator-Muster verwenden, in dem der Mediator diese Koordination kapselt. In diesem Szenario würde Mediator M Objekt A beobachten und würde Verweise auf Objekte B und C haben. Wenn A Ereignis X auslöst, wird M das Ereignis behandeln und BY () und CZ () in der vorgeschriebenen Reihenfolge aufrufen.

Wenn die Objekte A, B und C sich gegenseitig beobachten müssen, kann die Verwendung eines Vermittlers als Vermittler diese Objekte erheblich entkoppeln und Spaghetti-Code vermeiden.

Raymond Saltrelli
quelle
5

Das ObserverMuster wird verwendet, wenn eine Aktion für eine Klasse (die beobachtete Klasse) eine Reaktion in einer anderen Klasse (der beobachtenden Klasse) hervorrufen muss, die beobachtete Klasse jedoch nicht an die beobachtende Klasse gekoppelt werden soll. Dies ist ein sehr verbreitetes Muster. Der SAX XML-Parser kann ein gutes Beispiel sein. Um den SAX-Parser zu verwenden, implementiert ein Client die ContentHandlerSchnittstelle, um die Parser-Operation zu "beobachten". Wenn der Parser auf Elemente des XML-Dokuments stößt, ruft er Methoden von auf ContentHandler. Der Parser kann Client-Code aufrufen, der Parser ist jedoch nicht an den Client-Code gekoppelt.

Das MediatorMuster ist eine Verkapselung eines Verwendungsmusters einer Menge von Objekten. Client-Code wird nur an den Mediator gekoppelt, anstatt an mehrere andere Klassen. Dies ähnelt der Aggregation, mit der Ausnahme, dass die Lebensdauer der eingekapselten Objekte unabhängig von der Lebensdauer des Mediators ist.

Kevin Cline
quelle
1

In einfachen Worten (die ich benutze, um mich daran zu erinnern):

Beobachter: Verwenden Sie diese Option, wenn ein Objekt über Zustandsänderungen in einem anderen Objekt informiert werden möchte.

Um den Mediator zu verstehen, fällt es mir leichter, wenn Sie zuerst Facade betrachten: Facade aggregiert die Funktionalität einzelner Klassen (manchmal ganzer Subsysteme) und stellt diese Funktionalität in einer einzigen Schnittstelle bereit.

Mediator: Wie Facade, mit der Ausnahme, dass die Funktionalität aller Aggregatklassen kombiniert wird, um eine neue Funktionalität zu erzeugen . (Gute Erklärung hier )

Steven Evers
quelle