Frage

Hat jemand schon einmal das Brücke Muster in einer realen Welt Anwendung verwendet? Wenn ja, wie haben Sie es verwenden? Ist es mir, oder ist es nur die Adapter-Muster mit wenig Dependency Injection in den Mix geworfen? Ist es wirklich sein eigenes Muster verdienen?

War es hilfreich?

Lösung

Ein klassisches Beispiel für die Brückenmuster wird in der Definition von Formen in einer UI-Umgebung verwendet (siehe Brücke Muster Wikipedia-Eintrag ). Die Brücke Muster ist ein Verbund der < a href = "http://en.wikipedia.org/wiki/Template_method_pattern" rel = "noreferrer"> Vorlage und Strategie Muster.

Es ist eine verbreitete Ansicht einig Aspekte der Adapter-Muster in den Brücke-Mustern. Doch von diesem Artikel zu zitieren:

  

Auf den ersten Blick sieht die Brücke Muster viel wie der Adapter-Muster, dass eine Klasse verwendet wird, eine Art Schnittstelle in ein anderes zu konvertieren. Allerdings ist die Absicht der Adapter-Muster einer oder mehr Klassen Schnittstellen das gleiche wie die eine bestimmten Klasse aussehen zu lassen. Die Brücke Muster sind so konzipiert, ein Klasse-Schnittstelle von der Implementierung zu trennen, so dass Sie die Implementierung ohne Änderung des Client-Code ändern oder ersetzen können.

Andere Tipps

Es ist eine Kombination von Federicos und John Antworten.

Wann:

                   ----Shape---
                  /            \
         Rectangle              Circle
        /         \            /      \
BlueRectangle  RedRectangle BlueCircle RedCircle

Umgestalten zu:

          ----Shape---                        Color
         /            \                       /   \
Rectangle(Color)   Circle(Color)           Blue   Red

Die Brücke Muster sind eine Anwendung der alten Beratung „bevorzugen Komposition der Vererbung“. Es wird praktisch, wenn Sie verschiedene Zeiten in einer Weise, Unterklasse muss, die mit orthogonal zueinander sind. Sagen Sie bitte eine Hierarchie von farbigen Formen implementieren müssen. Sie würden nicht-Form mit dem Rechteck und Kreis Unterklasse und dann Unterklasse Rechteck mit redRectangle, BlueRectangle und GreenRectangle und das gleiche für Kreis, würden Sie? 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 nicht eine „Hierarchie der Farben“ implementieren, aber Sie bekommen die Idee ...

Wann:

        A
     /     \
    Aa      Ab
   / \     /  \
 Aa1 Aa2  Ab1 Ab2

Umgestalten zu:

     A         N
  /     \     / \
Aa(N) Ab(N)  1   2

Adapter und Brücke sind sicherlich im Zusammenhang, und der Unterschied ist subtil. Es ist wahrscheinlich, dass einige Leute, die denken, dass sie eines dieser Muster verwenden werden, um die anderen Muster tatsächlich verwendet wird.

Die Erklärung, die ich gesehen habe, ist, dass Adapter verwendet wird, wenn Sie versuchen, die Schnittstellen einiger inkompatibel Klassen zu vereinigen, dass bereits vorhanden . Die Adapter fungiert als eine Art Übersetzer für Implementierungen, die in Betracht gezogen werden könnte Vermächtnis .

Während das Brückenmuster wird für Code verwendet, die eher der grünen Wiese werden. Sie entwerfen die Brücke eine abstrakte Schnittstelle für eine Implementierung zur Verfügung zu stellen, die sich ändern muss, aber Sie definieren auch die Schnittstelle dieser Implementierungsklassen.

Gerätetreiber ist ein oft zitiertes Beispiel der Brücke, aber ich würde sagen, es ist eine Brücke ist, wenn Sie die Schnittstelle Spezifikation für Gerätehersteller sind zu definieren, aber es ist ein Adapter, wenn Sie vorhandene Gerätetreiber sind zu nehmen und einen Wrapper machen -Klasse eine einheitliche Schnittstelle zur Verfügung zu stellen.

So Code-weise, sind die beiden Muster sehr ähnlich. Business-weise, sie sind anders.

Siehe auch http://c2.com/cgi/wiki?BridgePattern

Nach meiner Erfahrung ist Brücke ein ziemlich häufig wiederkehrenden Muster, weil es die Lösung ist, wenn gibt es zwei orthogonale Dimensionen in der Domäne . Z.B. Formen und Ziehverfahren, Verhaltensweisen und Plattformen, Dateiformate und Serializer und so weiter.

Und ein Rat: Denken Sie immer von Design Patterns von der konzeptionellen Perspektive , nicht aus der Umsetzung Perspektive. Von der rechten Sicht Bridge kann nicht mit Adapter verwechselt werden, weil sie ein anderes Problem zu lösen, und die Zusammensetzung überlegen ist nicht auf Erbschaft wegen der um ihrer selbst willen, sondern weil es erlaubt separat orthogonal Bedenken zu behandeln.

Die Absicht von Brücke und Adapter ist anders und wir müssen beide separat Muster.

Bridge Muster:

  1. Es ist ein Strukturmuster
  2. Abstraktion und Implementierung sind nicht bei der Kompilierung
  3. gebunden
  4. Abstraktion und Umsetzung - sowohl ohne Auswirkungen auf Client variieren
  5. Verwendet Komposition der Vererbung.

Mit der Brücke Muster, wenn:

  1. Sie möchten Laufzeit der Umsetzung verbindlich,
  2. Sie haben eine Proliferation von Klassen aus einer gekoppelten Schnittstelle und zahlreichen Implementierungen führen,
  3. Sie wollen eine Implementierung von mehreren Objekten teilen,
  4. Sie müssen orthogonal Klassenhierarchien kartieren.

@ John Sonmez Antwort zeigt deutlich die Wirksamkeit der Brückenstruktur Klassenhierarchie zu reduzieren.

Sie auf unter Dokumentation Link verweisen besseren Einblick in die Brückenstruktur mit Codebeispiel

bekommen

Adapter Muster :

  1. Es können zwei unabhängige Schnittstellen zusammenarbeiten durch die verschiedenen Objekte, die möglicherweise dieselbe Rolle zu spielen.
  2. Es ändert Original-Schnittstelle.

Die wichtigsten Unterschiede:

  1. Adapter macht die Dinge funktionieren, nachdem sie entworfen wird; Brücke macht sie arbeiten, bevor sie sind.
  2. Brücke ist up-front gestaltet die Abstraktion und die Umsetzung lassen variieren unabhängig . Adapter ist nachrüstbar an unabhängige Klassen machen zusammen arbeiten.
  3. Die Absicht: Adapter können zwei unabhängige Schnittstellen zusammen zu arbeiten. Brücke ermöglicht Abstraktion und Implementierung unabhängig zu verändern.

Related SE Frage mit UML-Diagramm und Arbeits Code:

Unterschied zwischen Brückenmuster und Adapter Muster

Nützliche Artikel:

sourcemaking Brücke Muster Artikel

sourcemaking Adapter Muster Artikel

journaldev Brücke Muster Artikel

EDIT:

Bridge-Muster reale Welt Beispiel (Stand meta.stackoverflow.com Vorschlag aufgenommen Dokumentation Website Beispiel in diesem Beitrag, da Dokumentation wird mich sonnen set)

Bridge Muster abkoppelt Abstraktion von der Implementierung, so dass beide unabhängig voneinander variieren können. Es wird mit der Zusammensetzung erreicht, anstatt Vererbung.

Bridge Muster UML aus Wikipedia:

 Brücke Muster UML aus Wikipedia

Sie haben vier Komponenten in diesem Muster.

Abstraction: Es definiert eine Schnittstelle

RefinedAbstraction: Es implementiert Abstraktion:

Implementor: Es definiert eine Schnittstelle für die Implementierung

ConcreteImplementor:. Es implementiert Implementor Schnittstelle

The crux of Bridge pattern : Zwei orthogonale Klassenhierarchien mit Zusammensetzung (und kein Erbe). Die Abstraktionshierarchie und Implementierung Hierarchie unabhängig voneinander variieren können. Die Umsetzung nie bezieht sich Abstraktion. Abstraction enthält Implementation Schnittstelle als Mitglied (durch die Zusammensetzung). Diese Zusammensetzung reduziert eine weitere Ebene der Vererbungshierarchie.

Echt Wort Anwendungsfall:

verschiedene Fahrzeuge aktivieren beide Versionen von manuellen und automatischen Getriebesystem haben.

Beispielcode:

/* Implementor interface*/
interface Gear{
    void handleGear();
}

/* Concrete Implementor - 1 */
class ManualGear implements Gear{
    public void handleGear(){
        System.out.println("Manual gear");
    }
}
/* Concrete Implementor - 2 */
class AutoGear implements Gear{
    public void handleGear(){
        System.out.println("Auto gear");
    }
}
/* Abstraction (abstract class) */
abstract class Vehicle {
    Gear gear;
    public Vehicle(Gear gear){
        this.gear = gear;
    }
    abstract void addGear();
}
/* RefinedAbstraction - 1*/
class Car extends Vehicle{
    public Car(Gear gear){
        super(gear);
        // initialize various other Car components to make the car
    }
    public void addGear(){
        System.out.print("Car handles ");
        gear.handleGear();
    }
}
/* RefinedAbstraction - 2 */
class Truck extends Vehicle{
    public Truck(Gear gear){
        super(gear);
        // initialize various other Truck components to make the car
    }
    public void addGear(){
        System.out.print("Truck handles " );
        gear.handleGear();
    }
}
/* Client program */
public class BridgeDemo {    
    public static void main(String args[]){
        Gear gear = new ManualGear();
        Vehicle vehicle = new Car(gear);
        vehicle.addGear();

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

        gear = new ManualGear();
        vehicle = new Truck(gear);
        vehicle.addGear();

        gear = new AutoGear();
        vehicle = new Truck(gear);
        vehicle.addGear();
    }
}

Ausgabe:

Car handles Manual gear
Car handles Auto gear
Truck handles Manual gear
Truck handles Auto gear

Erklärung:

  1. Vehicle ist eine Abstraktion.
  2. Car und Truck sind zwei konkrete Implementierungen von Vehicle.
  3. Vehicle definiert eine abstrakte Methode: addGear().
  4. Gear ist Implementierer Schnittstelle
  5. ManualGear und AutoGear sind zwei Implementierungen von Gear
  6. Vehicle enthält implementor Schnittstelle statt der Umsetzung der Schnittstelle. Compositon von Implementierer Schnittstelle Kern dieses Muster: Es ermöglicht Abstraktion und Implementierung unabhängig variieren
  7. .
  8. Car und Truck definieren Implementierung (neu definiert Abstraktion) zur Abstraktion: addGear(): Es enthält Gear - Entweder Manual oder Auto

Use Case (e) für Brückenmuster :

  1. Abstraktion und Implementierung können sie unabhängig ändern, und sie sind nicht bei der Kompilierung
  2. gebunden
  3. Karte orthogonale Hierarchien - Einer für Abstraktion und einen für Implementierung .

Ich habe das Brückenmuster bei der Arbeit verwendet. I-Programm in C ++, wo es oft das PIMPL Idiom (Zeiger auf Implementierung) aufgerufen wird. Es sieht wie folgt aus:

class A
{
public: 
  void foo()
  {
    pImpl->foo();
  }
private:
  Aimpl *pImpl;
};

class Aimpl
{
public:
  void foo();
  void bar();
};  

In diesem Beispiel class A enthält die Schnittstelle, und class Aimpl enthält die Implementierung.

Eine Verwendung für dieses Muster ist nur ein Teil der öffentlichen Mitglieder der Implementierungsklasse zu belichten, anderen aber nicht. Im Beispiel nur Aimpl::foo() kann durch die öffentliche Schnittstelle von A genannt werden, aber nicht Aimpl::bar()

Ein weiterer Vorteil ist, dass Sie Aimpl in einer separaten Header-Datei zu definieren, die brauchen nicht von den Nutzern A enthalten sein. Alles, was Sie tun müssen, ist eine Vorwärtserklärung Aimpl vor A wird definiert verwenden und die Definitionen aller Mitgliedsfunktionen Referenzierung pImpl in die CPP-Datei bewegen. Dies gibt Ihnen die Möglichkeit, den Aimpl Header privat, zu halten und die Kompilierung zu reduzieren.

Um Form Beispiel in Code zu setzen:

#include<iostream>
#include<string>
#include<cstdlib>

using namespace std;

class IColor
{
public:
    virtual string Color() = 0;
};

class RedColor: public IColor
{
public:
    string Color()
    {
        return "of Red Color";
    }
};

class BlueColor: public IColor
{
public:
    string Color()
    {
        return "of Blue Color";
    }
};


class IShape
{
public:
virtual string Draw() = 0;
};

class Circle: public IShape
{
        IColor* impl;
    public:
        Circle(IColor *obj):impl(obj){}
        string Draw()
        {
            return "Drawn a Circle "+ impl->Color();
        }
};

class Square: public IShape
{
        IColor* impl;
    public:
        Square(IColor *obj):impl(obj){}
        string Draw()
        {
        return "Drawn a Square "+ impl->Color();;
        }
};

int main()
{
IColor* red = new RedColor();
IColor* blue = new BlueColor();

IShape* sq = new Square(red);
IShape* cr = new Circle(blue);

cout<<"\n"<<sq->Draw();
cout<<"\n"<<cr->Draw();

delete red;
delete blue;
return 1;
}

Die Ausgabe lautet:

Drawn a Square of Red Color
Drawn a Circle of Blue Color

Beachten Sie die Leichtigkeit, mit der neuen Farben und Formen können aufgrund Permutationen ohne dass es zu einer Explosion von Subklassen zu dem System hinzugefügt werden.

für mich denke ich, es als ein Mechanismus, bei dem Sie Schnittstellen tauschen können. In der realen Welt, die Sie vielleicht eine Klasse, die mehr als eine Schnittstelle verwenden können, Brücke können Sie tauschen.

Bridge design pattern we can easily understand helping of service and dao layer.

Dao layer -> create common interface for dao layer ->
public interface Dao<T>{
void save(T t);
}
public class AccountDao<Account> implement Dao<Account>{
public void save(Account){
}
}
public LoginDao<Login> implement Dao<Login>{
public void save(Login){
}
}
Service Layer ->
1) interface
public interface BasicService<T>{
    void save(T t);
}
concrete  implementation of service -
Account service -
public class AccountService<Account> implement BasicService<Account>{
 private Dao<Account> accountDao;
 public AccountService(AccountDao dao){
   this.accountDao=dao;
   }
public void save(Account){
   accountDao.save(Account);
 }
}
login service- 
public class LoginService<Login> implement BasicService<Login>{
 private Dao<Login> loginDao;
 public AccountService(LoginDao dao){
   this.loginDao=dao;
   }
public void save(Login){
   loginDao.save(login);
 }
}

public class BridgePattenDemo{
public static void main(String[] str){
BasicService<Account> aService=new AccountService(new AccountDao<Account>());
Account ac=new Account();
aService.save(ac);
}
}
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top