Hat jemand jemals das Brückenmuster in einer realen Anwendung verwendet? Wenn ja, wie haben Sie es verwendet? Bin ich es oder ist es nur das Adaptermuster mit einer kleinen Abhängigkeitsinjektion, die in die Mischung geworfen wird? Hat es wirklich ein eigenes Muster verdient?
design-patterns
adapter
bridge
Charles Graham
quelle
quelle
Antworten:
Ein klassisches Beispiel für das Bridge-Muster wird bei der Definition von Formen in einer UI-Umgebung verwendet (siehe Wikipedia-Eintrag Bridge-Muster ). Die Brücke Muster ist ein Verbund der Vorlage und Strategie - Muster.
Es ist eine gängige Ansicht, einige Aspekte des Adaptermusters im Brückenmuster. Um jedoch aus diesem Artikel zu zitieren :
quelle
Es gibt eine Kombination aus Federicos und Johns Antworten.
Wann:
Refactor zu:
quelle
Das Brückenmuster ist eine Anwendung des alten Hinweises "Komposition gegenüber Vererbung bevorzugen". Dies ist praktisch, wenn Sie verschiedene Zeiten orthogonal zueinander unterordnen müssen. Angenommen, Sie müssen eine Hierarchie farbiger Formen implementieren. Sie würden Shape nicht mit Rectangle und Circle unterordnen und dann Rectangle mit RedRectangle, BlueRectangle und GreenRectangle und das Gleiche für Circle, oder? Sie würden es vorziehen , zu sagen , dass jede Form hat eine Farbe und eine Hierarchie von Farben zu implementieren, und das ist die Brücke - Muster. Nun, ich würde keine "Hierarchie der Farben" implementieren, aber Sie bekommen die Idee ...
quelle
Wann:
Refactor zu:
quelle
Adapter und Brücke sind sicherlich verwandt, und die Unterscheidung ist subtil. Es ist wahrscheinlich, dass einige Leute, die glauben, eines dieser Muster zu verwenden, tatsächlich das andere Muster verwenden.
Die Erklärung, die ich gesehen habe, ist, dass Adapter verwendet wird, wenn Sie versuchen, die Schnittstellen einiger bereits vorhandener inkompatibler Klassen zu vereinheitlichen . Der Adapter fungiert als eine Art Übersetzer für Implementierungen, die als Legacy angesehen werden können .
Während das Bridge-Muster für Code verwendet wird, bei dem es sich eher um eine grüne Wiese handelt. Sie entwerfen die Bridge so, dass sie eine abstrakte Schnittstelle für eine Implementierung bereitstellt, die variieren muss. Sie definieren jedoch auch die Schnittstelle dieser Implementierungsklassen.
Gerätetreiber sind ein häufig genanntes Beispiel für Bridge, aber ich würde sagen, es ist eine Bridge, wenn Sie die Schnittstellenspezifikation für Gerätehersteller definieren, aber es ist ein Adapter, wenn Sie vorhandene Gerätetreiber verwenden und eine Wrapper-Klasse erstellen Bereitstellung einer einheitlichen Schnittstelle.
In Bezug auf den Code sind die beiden Muster also sehr ähnlich. In geschäftlicher Hinsicht sind sie anders.
Siehe auch http://c2.com/cgi/wiki?BridgePattern
quelle
Nach meiner Erfahrung ist Bridge ein häufig wiederkehrendes Muster, da es die Lösung ist, wenn zwei orthogonale Dimensionen in der Domäne vorhanden sind . ZB Formen und Zeichenmethoden, Verhaltensweisen und Plattformen, Dateiformate und Serializer usw.
Und ein Rat: Denken Sie immer an Entwurfsmuster aus konzeptioneller Sicht , nicht aus Sicht der Implementierung. Aus der richtigen Sicht kann Bridge nicht mit Adapter verwechselt werden, da sie ein anderes Problem lösen und die Zusammensetzung der Vererbung nicht aus eigenen Gründen überlegen ist, sondern weil sie es ermöglicht, orthogonale Bedenken separat zu behandeln.
quelle
Die Absicht von Bridge und Adapter ist unterschiedlich und wir benötigen beide Muster getrennt.
Brückenmuster:
Verwenden Sie das Brückenmuster, wenn:
Die Antwort von @ John Sonmez zeigt deutlich die Wirksamkeit des Brückenmusters bei der Reduzierung der Klassenhierarchie.
Unter dem folgenden Dokumentationslink finden Sie einen besseren Einblick in das Brückenmuster anhand eines Codebeispiels
Adaptermuster :
Hauptunterschiede:
Verwandte SE-Frage mit UML-Diagramm und Arbeitscode:
Unterschied zwischen Brückenmuster und Adaptermuster
Nützliche Artikel:
Artikel zur Herstellung von Brückenmustern
Artikel zur Herstellung von Quellenadaptern
journaldev Brückenmuster Artikel
BEARBEITEN:
Beispiel für ein Bridge-Muster in der realen Welt (Gemäß dem Vorschlag von meta.stackoverflow.com wurde ein Beispiel für eine Dokumentationssite in diesen Beitrag aufgenommen, da die Dokumentation untergehen wird.)
Das Brückenmuster entkoppelt die Abstraktion von der Implementierung, sodass beide unabhängig voneinander variieren können. Es wurde eher mit Komposition als mit Vererbung erreicht.
Brückenmuster UML aus Wikipedia:
Sie haben vier Komponenten in diesem Muster.
Abstraction
: Es definiert eine SchnittstelleRefinedAbstraction
: Es implementiert Abstraktion:Implementor
: Es definiert eine Schnittstelle für die ImplementierungConcreteImplementor
: Es implementiert die Implementiererschnittstelle.The crux of Bridge pattern :
Zwei orthogonale Klassenhierarchien mit Komposition (und ohne Vererbung). Die Abstraktionshierarchie und die Implementierungshierarchie können unabhängig voneinander variieren. Die Implementierung bezieht sich niemals auf Abstraktion. Die Abstraktion enthält die Implementierungsschnittstelle als Mitglied (durch Komposition). Diese Zusammensetzung reduziert eine weitere Ebene der Vererbungshierarchie.Echtes Wort Anwendungsfall:
Ermöglichen Sie verschiedenen Fahrzeugen, sowohl Versionen des manuellen als auch des automatischen Getriebesystems zu haben.
Beispielcode:
Ausgabe:
Erläuterung:
Vehicle
ist eine Abstraktion.Car
undTruck
sind zwei konkrete Implementierungen vonVehicle
.Vehicle
definiert eine abstrakte Methode :addGear()
.Gear
ist ImplementiererschnittstelleManualGear
undAutoGear
sind zwei Implementierungen vonGear
Vehicle
enthält eineimplementor
Schnittstelle, anstatt die Schnittstelle zu implementieren.Compositon
der Implementiererschnittstelle ist der Kern dieses Musters: Es ermöglicht, dass Abstraktion und Implementierung unabhängig voneinander variieren.Car
undTruck
definieren Sie die Implementierung (neu definierte Abstraktion) für die AbstraktionaddGear()
:: Sie enthältGear
- EntwederManual
oderAuto
Anwendungsfall (e) für das Brückenmuster :
quelle
Ich habe das Brückenmuster bei der Arbeit verwendet. Ich programmiere in C ++, wo es oft als PIMPL-Idiom (Zeiger auf die Implementierung) bezeichnet wird. Es sieht aus wie das:
In diesem Beispiel
class A
enthält die Schnittstelle undclass Aimpl
die Implementierung.Eine Verwendung für dieses Muster besteht darin, nur einige der öffentlichen Mitglieder der Implementierungsklasse verfügbar zu machen, andere jedoch nicht. Im Beispiel
Aimpl::foo()
kann nur über die öffentliche Schnittstelle von aufgerufen werdenA
, aber nichtAimpl::bar()
Ein weiterer Vorteil ist, dass Sie
Aimpl
in einer separaten Header-Datei definieren können, die von den Benutzern von nicht enthalten sein mussA
. Sie müssen lediglich eine Vorwärtsdeklaration verwenden,Aimpl
bevorA
definiert wurde, und die Definitionen aller Mitgliedsfunktionen, auf die verwiesen wird,pImpl
in die CPP-Datei verschieben. Auf diese Weise können Sie denAimpl
Header privat halten und die Kompilierungszeit verkürzen.quelle
So fügen Sie ein Formbeispiel in den Code ein:
Die Ausgabe ist:
Beachten Sie die Leichtigkeit, mit der neue Farben und Formen zum System hinzugefügt werden können, ohne dass es aufgrund von Permutationen zu einer Explosion von Unterklassen kommt.
quelle
Für mich ist es ein Mechanismus, mit dem Sie Schnittstellen austauschen können. In der realen Welt haben Sie möglicherweise eine Klasse, die mehr als eine Schnittstelle verwenden kann. Mit Bridge können Sie tauschen.
quelle
Sie arbeiten für eine Versicherungsgesellschaft, in der Sie eine Workflow-Anwendung entwickeln, die verschiedene Aufgaben verwaltet: Buchhaltung, Vertrag, Schadensfälle. Dies ist die Abstraktion. Auf der Implementierungsseite müssen Sie in der Lage sein, Aufgaben aus verschiedenen Quellen zu erstellen: E-Mail, Fax, E-Messaging.
Sie beginnen Ihr Design mit diesen Klassen:
Da nun jede Quelle auf eine bestimmte Weise behandelt werden muss, entscheiden Sie sich, jeden Aufgabentyp zu spezialisieren:
Sie haben 13 Klassen. Das Hinzufügen eines Aufgabentyps oder eines Quelltyps wird zu einer Herausforderung. Die Verwendung des Brückenmusters führt zu einer einfacheren Wartung, indem die Aufgabe (die Abstraktion) von der Quelle entkoppelt wird (was ein Implementierungsproblem darstellt):
Das Hinzufügen eines Aufgabentyps oder einer Quelle ist jetzt viel einfacher.
Hinweis: Die meisten Entwickler würden die 13 Klassenhierarchie nicht im Voraus erstellen, um dieses Problem zu beheben. Im wirklichen Leben kennen Sie die Anzahl der Quell- und Aufgabentypen jedoch möglicherweise nicht im Voraus. Wenn Sie nur eine Quelle und zwei Aufgabentypen haben, würden Sie die Aufgabe wahrscheinlich nicht von der Quelle entkoppeln. Dann wächst die Gesamtkomplexität, wenn neue Quellen und Aufgabentypen hinzugefügt werden. Irgendwann werden Sie umgestalten und erhalten meistens eine brückenartige Lösung.
quelle
quelle