web-dev-qa-db-de.com

Unterschied zwischen Brückenmuster und Adaptermuster

Was ist der Unterschied zwischen den Brücken- und Adaptermustern?

96
Firoz

"Der Adapter lässt die Dinge funktionieren, nachdem sie entworfen wurden; Bridge macht sie Arbeit, bevor sie sind. [GoF, p219]"

Das Adapter - Muster ist effektiv, wenn Sie über vorhandenen Code verfügen, sei es von Drittanbietern oder intern, aber außerhalb Ihrer Kontrolle oder auf andere Weise nicht veränderbar, um die gewünschte Schnittstelle zu erreichen. Zum Beispiel haben wir einen SuperWeaponsArray, der eine Reihe von Doomsday-Geräten steuern kann. 

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}

Großartig. Außer wir wissen, dass wir in unserem Arsenal ein nukleares Gerät haben, das der Umwandlung in die Waffen-Schnittstelle weit vorausgeht. Aber wir möchten, dass es hier wirklich gut funktioniert. Was machen wir also? 

NukeWeaponsAdaptor - basiert auf unserer Nuke-Klasse, exportiert jedoch die Weapon-Schnittstelle. Süß, jetzt können wir die Welt sicher zerstören. Es scheint ein wenig kludge zu sein, aber es macht die Dinge funktionieren.


Das BridgePattern ist eine Implementierung, die Sie im Vorfeld implementieren. Wenn Sie wissen, dass Sie zwei orthogonale Hierarchien haben, können Sie die Schnittstelle und die Implementierung so entkoppeln, dass Sie keine verrückte Anzahl von Klassen erhalten. Nehmen wir an, Sie haben:

Typen von Dateiobjekten vom Typ MemoryMappedFile und DirectReadFile. Angenommen, Sie möchten Dateien aus verschiedenen Quellen lesen können (möglicherweise Linux- oder Windows-Implementierungen usw.). Bridge hilft Ihnen zu vermeiden, dass Sie mit: 

MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile

145
James

http://en.wikipedia.org/wiki/Adapter_pattern

Beim Adapter-Muster geht es eher darum, den vorhandenen Code mit einem neueren System oder einer neueren Schnittstelle zusammenarbeiten zu lassen.

Wenn Sie über eine Reihe von Web-Service-APIs verfügen, die dem Unternehmensstandard entsprechen, die Sie der vorhandenen Erweiterungsschnittstelle einer anderen Anwendung anbieten möchten, können Sie dies in Betracht ziehen. Beachten Sie, dass es eine graue Fläche gibt, und es geht mehr darum, wie Sie das Muster technisch definieren, da andere Muster wie die Fassade sich ähneln.

http://en.wikipedia.org/wiki/Bridge_pattern

Das Bridge-Muster ermöglicht Ihnen möglicherweise alternative Implementierungen eines Algorithmus oder Systems.

Wenn auch kein klassisches Bridge-Musterbeispiel, stellen Sie sich vor, Sie hätten einige Implementierungen eines Datenspeichers: Die eine ist effizient im Raum, die andere ist effizient in der Rohperformance .

In Bezug auf Ihre Frage "Wo kann ich welches Muster verwenden?" Lautet die Antwort, wo immer es für Ihr Projekt sinnvoll ist! Überlegen Sie sich vielleicht, ob Sie eine Klarstellung anbieten, um die Diskussion darüber zu leiten, wo Sie glauben, dass Sie das eine oder das andere brauchen.

13
Jeff Wilcox

Adapter:

  1. Es ist ein strukturelles Muster
  2. Es ist nützlich, mit zwei inkompatiblen Schnittstellen zu arbeiten

UML-Diagramm: aus dofactory article:

 enter image description here

Ziel: Definiert die domänenspezifische Schnittstelle, die der Client verwendet.

Adapter: Anpassung des Schnittstellenadapters an die Zielschnittstelle.

Adaptee: Definiert eine vorhandene Schnittstelle, die angepasst werden muss.

Client: arbeitet mit Objekten zusammen, die der Target-Schnittstelle entsprechen.

Beispiel:

Quadrat und Rechteck sind zwei verschiedene Formen, und das Abrufen von area () von jeder von ihnen erfordert unterschiedliche Methoden. Aber immer noch arbeiten Square am Rectangle Interface mit der Konvertierung einiger Eigenschaften.

public class AdapterDemo{
    public static void main(String args[]){
        SquareArea s = new SquareArea(4);
        System.out.println("Square area :"+s.getArea());
    }
}

class RectangleArea {
    public int getArea(int length, int width){
        return length * width;
    }
}

class SquareArea extends RectangleArea {

    int length;
    public SquareArea(int length){
        this.length = length;
    }
    public int getArea(){
        return getArea(length,length);
    }
}

Brücke:

  1. Es ist ein strukturelles Muster
  2. es entkoppelt eine Abstraktion von der Implementierung und beide können unabhängig voneinander variieren
  3. Dies ist möglich, weil die Zusammensetzung anstelle der Vererbung verwendet wurde

EDIT: (gemäß dem @quasoft-Vorschlag)

Sie haben vier Komponenten in diesem Muster.

  1. Abstraktion: Definiert eine Schnittstelle

  2. RefinedAbstraction: Es implementiert Abstraktion:

  3. Implementor: Definiert eine Schnittstelle für die Implementierung

  4. ConcreteImplementor: Implementiert die Implementor-Schnittstelle.

Code-Auszug:

Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();

gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();

Verwandte Post:

Wann verwenden Sie das Brückenmuster? Wie unterscheidet es sich vom Adaptermuster?

Hauptunterschiede: von Sourcecaking Artikel

  1. Der Adapter lässt die Dinge funktionieren, nachdem sie entworfen wurden. Bridge lässt sie arbeiten, bevor sie es sind.
  2. Bridge ist so konzipiert, dass Abstraktion und Implementierung unabhängig voneinander variieren können. Der Adapter wurde nachgerüstet, damit nicht miteinander verbundene Klassen zusammenarbeiten können.
8
Ravindra babu

Dieser Post ist schon eine Weile her. Es ist jedoch wichtig zu verstehen, dass eine Fassade einem Adapter etwas ähnelt, jedoch nicht ganz dasselbe. Ein Adapter "passt" eine vorhandene Klasse an eine normalerweise nicht kompatible Clientklasse an. Nehmen wir an, Sie haben ein altes Workflow-System, das Ihre Anwendung als Client verwendet. Möglicherweise ersetzt Ihr Unternehmen das Workflow-System durch ein neues "inkompatibles" System (in Bezug auf Schnittstellen). In den meisten Fällen können Sie das Adaptermuster und den Schreibcode verwenden, der die Schnittstellen der neuen Workflow-Engine tatsächlich aufruft. Eine Brücke wird im Allgemeinen anders verwendet. Wenn Sie tatsächlich über ein System verfügen, das mit verschiedenen Dateisystemen arbeiten muss (z. B. lokale Festplatte, NFS usw.), können Sie das Brückenmuster verwenden und eine Abstraktionsschicht erstellen, um mit allen Dateisystemen zu arbeiten. Dies wäre im Grunde ein einfacher Anwendungsfall für das Brückenmuster. Die Fassade und der Adapter haben einige Eigenschaften gemeinsam, aber Fassaden werden normalerweise verwendet, um eine vorhandene Schnittstelle/Klasse zu vereinfachen. In den Anfängen von EJBs gab es keine lokalen Anrufe für EJBs. Die Entwickler haben den Stub immer beschafft, eingegrenzt und als "Pseudo-Remote" bezeichnet. Dies führte häufig zu Leistungsproblemen (vor allem, wenn wirklich über die Leitung gerufen wurde). Erfahrene Entwickler würden das Fassadenmuster verwenden, um dem Kunden eine sehr grobkörnige Schnittstelle bereitzustellen. Diese Fassade würde dann wiederum mehrere Aufrufe für verschiedene feinkörnigere Methoden durchführen. Insgesamt wurde dadurch die Anzahl der erforderlichen Methodenaufrufe erheblich reduziert und die Leistung erhöht.

8
John Penner

Bridge ist Adapter verbessert. Bridge enthält einen Adapter und bietet zusätzliche Flexibilität. Hier werden Elemente aus Ravindras Antwort zwischen Mustern abgebildet:

      Adapter  |    Bridge
    -----------|---------------
    Target     | Abstraction
    -----------|---------------
               | RefinedAbstraction
               |
               |   This element is Bridge specific. If there is a group of 
               |   implementations that share the same logic, the logic can be placed here.
               |   For example, all cars split into two large groups: manual and auto. 
               |   So, there will be two RefinedAbstraction classes.
    -----------|--------------- 
    Adapter    | Implementor
    -----------|---------------
    Adaptee    | ConcreteImplementor
0
PolinaC

Angenommen, Sie haben eine abstrakte Shape-Klasse mit einer (generischen/abstrahierten) Zeichenfunktionalität und einem Circle, der die Shape implementiert. Brückenmuster ist einfach ein bidirektionaler Abstraktionsansatz, um die Implementierung (Zeichnen in Circle) und die generische/abstrahierte Funktionalität (Zeichnen in der Shape-Klasse) zu entkoppeln. 

Was heißt das wirklich? Auf den ersten Blick klingt es wie etwas, das Sie bereits machen (durch Inversion der Abhängigkeit). Keine Sorge, eine weniger oder weniger modulare Codebasis zu haben. Aber es ist eine etwas tiefere Philosophie dahinter.

Nach meinem Verständnis könnte sich das Bedürfnis nach Verwendungsmustern ergeben, wenn ich neue Klassen hinzufügen muss, die eng mit dem aktuellen System (wie RedCircle oder GreenCircle) verknüpft sind und sich durch eine einzige Funktionalität (wie Farbe) unterscheiden. Und ich brauche ein Bridge-Muster, insbesondere wenn die vorhandenen Systemklassen (Kreis oder Form) häufig geändert werden sollen und Sie nicht möchten, dass neu hinzugefügte Klassen von diesen Änderungen betroffen sind. Aus diesem Grund wird die generische Zeichnungsfunktionalität in eine neue Benutzeroberfläche abstrahiert, sodass Sie das Zeichnungsverhalten unabhängig von Form oder Kreis ändern können.

0
stdout