Brücke (Entwurfsmuster) - LinkFang.de





Brücke (Entwurfsmuster)


Eine Brücke (englisch bridge pattern) ist in der Softwareentwicklung ein Strukturmuster (englisch structural pattern), das zur Trennung der Implementierung von ihrer Abstraktion (Schnittstelle) dient. Dadurch können beide unabhängig voneinander verändert werden.[1] Es ist ein Entwurfsmuster der sogenannten GoF-Muster (siehe Viererbande).

Problem

Normalerweise wird eine Implementierung durch Vererbung der Abstraktion realisiert. Dies kann jedoch dazu führen, dass in der Vererbungshierarchie sowohl Implementierungen als auch andere abstrakte Klassen zu finden sind. Dies macht die Vererbungshierarchie unübersichtlich und schwer zu warten.

Lösung

Werden die abstrakten Klassen und die Implementierungen in zwei verschiedenen Hierarchien verwaltet, so gewinnt erstens die Übersichtlichkeit und zweitens wird die Anwendung unabhängig von der Implementierung.

Allgemeine Verwendung

Eine Brücke findet Anwendung, wenn

  • sowohl Abstraktion als auch Implementierung erweiterbar sein sollen und eine dauerhafte Verbindung zwischen Abstraktion und Implementierung verhindert werden soll,
  • Änderungen der Implementierung ohne Auswirkungen für den Klienten sein sollen,
  • die Implementierung vor dem Klienten verborgen bleiben soll, oder
  • die Implementierung von verschiedenen Klassen gleichzeitig genutzt werden soll.

In der Praxis kommt es oft vor, dass die Abstraktionsseite nicht so feingranular untergliedert wird wie die Implementierungsseite. Man spricht von einer degenerierten Brücke.

UML-Diagramm

Akteure

Die Abstraktion (im Beispiel: List) definiert einerseits die Schnittstelle der Abstraktion, andererseits hält sie eine Referenz zu einem Implementierer. Die SpezAbstraktion (im Beispiel: SortedList) erweitert die Schnittstelle. Der Implementierer (im Beispiel: ListImpl) definiert die Schnittstelle der Implementierung. Er kann sich dabei von der Schnittstelle der Abstraktion erheblich unterscheiden. Der KonkrImplementierer (im Beispiel: ArrayList) enthält eine konkrete Implementierung durch Implementierung der Schnittstelle.

Vorteile

Die Vorteile einer Brücke bestehen darin, dass Abstraktion und Implementierung entkoppelt werden. Die Implementierung ist außerdem während der Laufzeit dynamisch änderbar und die Erweiterbarkeit von Abstraktion und Implementierung wird verbessert.

Durch Angabe eines Parameters bei der Erzeugung einer Abstraktion kann die Implementierung gewählt werden, zudem wird die Implementierung für den Klienten vollständig versteckt. Eine starke Vergrößerung der Anzahl der Klassen kann vermieden werden.

Code-Beispiele

Java

abstract class Printer {
    protected PrintingImpl impl;
 
    public Printer(PrintingImpl impl) {
        this.impl = impl;
    }
 
    public abstract void print();
 
    public PrintingImpl getImpl() {
        return impl;
    }
 
    public void setImpl(PrintingImpl impl) {
        this.impl = impl;
    }
}
 
class APrinter extends Printer {
    public APrinter(PrintingImpl impl) {
        super(impl);
    }
 
    @Override
    public void print() {
        impl.print("A");
    }
}
 
class BPrinter extends Printer {
    public BPrinter(PrintingImpl impl) {
        super(impl);
    }
 
    @Override
    public void print() {
        impl.print("B");
    }
}
 
interface PrintingImpl {
    public void print(String what);
}
 
class PlainTextPrintingImpl implements PrintingImpl {
    @Override
    public void print(String what) {
        System.out.println(what);
    }
}
 
class HTMLPrintingImpl implements PrintingImpl {
    @Override
    public void print(String what) {
        System.out.println("<p>\n\t<em>" + what + "</em>\n</p>");
    }
}
 
public class Main {
    public static void main(String[] args) {
        Printer printer;
 
        PrintingImpl plainImpl = new PlainTextPrintingImpl();
        PrintingImpl htmlImpl = new HTMLPrintingImpl();
 
        printer = new APrinter(plainImpl);
        printer.print();
 
        /* Die PrintingImpl kann problemlos zur Laufzeit ausgetauscht
         * werden, da die Implementierung von der Abstraktion
         * entkoppelt ist. */
        printer.setImpl(htmlImpl);
        printer.print();
 
        /* Genauso kann (ähnlich wie beim Strategy-Pattern) der
         * Printer selbst zur Laufzeit geändert werden. */
        printer = new BPrinter(plainImpl);
        printer.print();
 
        printer.setImpl(htmlImpl);
        printer.print();
    }
}

Ausgabe:

A
<p>
  <em>A</em>
</p>
B
<p>
  <em>B</em>
</p>

Ruby

class Abstraction
  def initialize(implementor)
    @implementor = implementor
  end
 
  def operation
    raise 'Implementor-Objekt antwortet nicht auf die operation-Methode'
      unless @implementor.respond_to?(:operation)
    @implementor.operation
  end
end
 
class RefinedAbstraction < Abstraction
  def operation
    puts 'Starte Vorgang...'
    super
  end
end
 
class Implementor
  def operation
    puts 'Wichtige Schritte ausführen'
  end
end
 
class ConcreteImplementorA < Implementor
  def operation
    super
    puts 'Zusätzliche Schritte ausführen'
  end
end
 
class ConcreteImplementorB < Implementor
  def operation
    super
    puts 'Andere, zusätzliche Schritte ausführen'
  end
end
 
normal_with_a = Abstraction.new(ConcreteImplementorA.new)
normal_with_a.operation
# Wichtige Schritte ausführen
# Zusätzliche Schritte ausführen
 
normal_with_b = Abstraction.new(ConcreteImplementorB.new)
normal_with_b.operation
# Wichtige Schritte ausführen
# Andere, zusätzliche Schritte ausführen
 
refined_with_a = RefinedAbstraction.new(ConcreteImplementorA.new)
refined_with_a.operation
# Starte Vorgang...
# Wichtige Schritte ausführen
# Zusätzliche Schritte ausführen
 
refined_with_b = RefinedAbstraction.new(ConcreteImplementorB.new)
refined_with_b.operation
# Starte Vorgang...
# Wichtige Schritte ausführen
# Andere, zusätzliche Schritte ausführen

Verwandte Entwurfsmuster

Zum Erzeugen des Implementierungsobjekts der Brücke kann eine abstrakte Fabrik verwendet werden.

Ein Adapter ist der Brücke scheinbar ähnlich. Jedoch dient der Adapter einer nachträglichen Anpassung einer Klasse an eine Schnittstelle, während die Brücke eine gezielte Entscheidung zur Entkopplung ist. Beide Entwurfsmuster sind also gegensätzlich, können aber in ihrer Implementierung sehr ähnlich aussehen.

Einzelnachweise

  1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5. Auflage. Addison-Wesley, 1996, ISBN 3-8273-1862-9, S. 186.

Kategorien: Keine Kategorien vorhanden!

Quelle: Wikipedia - http://de.wikipedia.org/wiki/Brücke (Entwurfsmuster) (Vollständige Liste der Autoren des Textes [Versionsgeschichte])    Lizenz: CC-by-sa-3.0

Änderungen: Alle Bilder mit den meisten Bildunterschriften wurden entfernt. Ebenso alle zu nicht-existierenden Artikeln/Kategorien gehenden internen Wikipedia-Links (Bsp. Portal-Links, Redlinks, Bearbeiten-Links). Entfernung von Navigationsframes, Geo & Normdaten, Mediadateien, gesprochene Versionen, z.T. ID&Class-Namen, Style von Div-Containern, Metadaten, Vorlagen, wie lesenwerte Artikel. Ansonsten sind keine Inhaltsänderungen vorgenommen worden. Weiterhin kann es durch die maschinelle Bearbeitung des Inhalts zu Fehlern gerade in der Darstellung kommen. Darum würden wir jeden Besucher unserer Seite darum bitten uns diese Fehler über den Support mittels einer Nachricht mit Link zu melden. Vielen Dank!

Stand der Informationen: August 201& - Wichtiger Hinweis: Da die Inhalte maschinell von Wikipedia übernommen wurden, ist eine manuelle Überprüfung nicht möglich. Somit garantiert LinkFang.de nicht die Richtigkeit und Aktualität der übernommenen Inhalte. Sollten die Informationen mittlerweile fehlerhaft sein, bitten wir Sie darum uns per Support oder E-Mail zu kontaktieren. Wir werden uns dann innerhalb von spätestens 10 Tagen um Ihr Anliegen kümmern. Auch ohne Anliegen erfolgt mindestens alle drei Monate ein Update der gesamten Inhalte.