Was ist das Brückenmuster?
Das Brückenmuster ist ein strukturelles Designmuster. Mit anderen Worten: Seine Hauptaufgabe besteht darin, eine vollständige Struktur aus Klassen und Objekten zu erstellen. Eine Brücke erreicht dies, indem sie eine oder mehrere Klassen in separate Hierarchien unterteilt: Abstraktion und Implementierung . Eine Änderung der Funktionalität in einer Hierarchie zieht keine Änderung in der anderen nach sich. Das ist alles schön und gut, aber diese Definition ist sehr weit gefasst und beantwortet nicht die wichtigste Frage: „Was ist das Brückenmuster?“ Ich denke, es wird für Sie einfacher sein, die praktische Anwendung zu verstehen. Lassen Sie uns also gleich ein klassisches Szenario für das Brückenmuster erstellen. Wir haben eine abstrakteShapeKlasse, die eine generische geometrische Figur darstellt:
-
Shape.java
public abstract class Shape { public abstract void draw(); }Wenn wir uns entscheiden, Formen wie Dreiecke und Rechtecke hinzuzufügen, sorgen wir dafür, dass sie die
ShapeKlasse erben: -
Rechteck.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } } -
Triangle.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()Methode hängt von dieser Farbe ab. Um unterschiedliche Implementierungen der draw()Methode zu erhalten, müssen wir für jede Form-Farb-Kombination eine Klasse erstellen. Wenn wir drei Farben haben, brauchen wir sechs Klassen: TriangleBlack, TriangleGreen, TriangleRed, und . Sechs Unterrichtsstunden sind kein so großes Problem. Aber! Wenn wir eine neue Form oder Farbe hinzufügen müssen, wächst die Anzahl der Klassen exponentiell. Wie kommt man aus dieser Situation heraus? Das Speichern von Farben in einem Feld und das Aufzählen aller Optionen mithilfe von bedingten Anweisungen ist nicht die beste Lösung. Eine gute Lösung besteht darin, die Farbe auf eine separate Schnittstelle zu verschiebenRectangleBlackRectangleGreenRectangleRed. Gesagt, getan: Erstellen wir eine ColorSchnittstelle mit drei Implementierungen: BlackColor, GreenColorund RedColor:
-
Farbe.java:
public interface Color { void fillColor(); } -
BlackColor.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } } -
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } } -
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }Jetzt fügen wir
ColorderShapeKlasse ein Feld hinzu. Wir erhalten seinen Wert im Konstruktor. -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }Wir werden die
colorVariable inShapeImplementierungen verwenden. Das bedeutet, dass Shapes nun die Funktionalität derColorSchnittstelle nutzen können. -
Rechteck.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color colorFeld ist eine Brücke, die zwei separate Klassenhierarchien verbindet.
Wie man eine Brücke baut: Abstraktion und Implementierung
Schauen wir uns ein Klassendiagramm an, das das Brückenmuster darstellt:
Hier sehen Sie zwei unabhängige Strukturen, die geändert werden können, ohne die Funktionalität der anderen zu beeinträchtigen. In unserem Fall:
- Abstraktion ist die
ShapeKlasse - RefinedAbstraction ist die
Triangleund-RectangleKlasse - Implementor ist die
ColorSchnittstelle - ConcreteImplementor sind die Klassen
BlackColor,GreenColorund .RedColor
ShapeKlasse ist eine Abstraktion – ein Mechanismus zum Verwalten des Füllens von Formen mit verschiedenen Farben, der an die ColorSchnittstelle (Implementor) delegiert. Die Triangleund- RectangleKlassen sind konkrete Klassen, die den von der Klasse bereitgestellten Mechanismus verwenden Shape. BlackColorund GreenColorsind RedColorkonkrete Implementierungen in der Implementierungshierarchie.
Wo kann das Brückenmuster verwendet werden?
Ein großer Vorteil dieses Musters besteht darin, dass Sie Änderungen an den Funktionsklassen in einer Hierarchie vornehmen können, ohne die Logik der anderen zu zerstören. Außerdem trägt dieser Ansatz dazu bei, die Kopplung zwischen Klassen zu reduzieren. Die wichtigste Voraussetzung bei der Verwendung dieses Musters ist „Befolgen Sie die Anweisungen“ – ignorieren Sie keine davon! Lassen Sie uns zu diesem Zweck die Situationen herausfinden, in denen Sie unbedingt das Brückenmuster verwenden sollten:-
Wenn Sie die Anzahl der Elemente basierend auf Kombinationen zweier Konzepte (z. B. Formen und Farben) erweitern müssen.
-
Wenn Sie eine große Klasse, die nicht dem Prinzip der Einzelverantwortung entspricht, in kleinere Klassen mit eingeschränkter Funktionalität aufteilen möchten.
-
Wenn es notwendig ist, während der Ausführung des Programms Änderungen an der Logik bestimmter Entitäten vorzunehmen.
-
Wenn es notwendig ist, eine Implementierung vor den Clients der Klasse oder Bibliothek zu verbergen.
Vor- und Nachteile des Musters
Wie andere Muster hat eine Brücke sowohl Vor- als auch Nachteile. Vorteile des Brückenmusters:- Es verbessert die Skalierbarkeit des Codes – Sie können Funktionen hinzufügen, ohne befürchten zu müssen, dass etwas in einem anderen Teil des Programms kaputt geht.
- Es reduziert die Anzahl der Unterklassen, wenn die Anzahl der Entitäten andernfalls auf Kombinationen zweier Konzepte (z. B. Formen und Farben) basieren würde.
- Es ermöglicht die getrennte Arbeit an zwei separaten Hierarchien – Abstraktion und Implementierung. Zwei verschiedene Entwickler können Änderungen vornehmen, ohne sich in die Details des Codes des anderen zu vertiefen.
- Es reduziert die Kopplung zwischen Klassen – der einzige Ort, an dem die beiden Klassen gekoppelt sind, ist die Brücke (dh das
Color colorFeld).
- Abhängig von der spezifischen Situation und der Gesamtstruktur eines Projekts kann es sich negativ auf die Leistung eines Programms auswirken (z. B. wenn Sie mehr Objekte initialisieren müssen).
- Dadurch wird der Code schlechter lesbar, da zwischen den beiden Klassen gewechselt werden muss.
GO TO FULL VERSION