Was ist das Bridge-Muster?
Das Brückenmuster ist ein strukturelles Designmuster. Das heißt, seine Hauptaufgabe besteht darin, eine vollständige Struktur von Klassen und Objekten zu erstellen. Bridge löst dieses Problem, indem es eine oder mehrere Klassen in separate Hierarchien aufteilt – Abstraktion und Implementierung . Eine Änderung der Funktionalität in einer Hierarchie zieht keine Änderungen in einer anderen nach sich. Alles scheint klar, aber tatsächlich klingt diese Definition sehr weit gefasst und beantwortet nicht die Hauptfrage: „Was ist das Bridge-Muster?“ Ich denke, das wird Ihnen in der Praxis leichter fallen. Lassen Sie uns gleich ein klassisches Beispiel für das Bridge-Muster modellieren. Wir haben eine abstrakte KlasseShape
, die im Allgemeinen eine geometrische Figur beschreibt:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
Wenn wir uns entscheiden, Dreiecks- und Rechteckformen hinzuzufügen, erben wir von der Klasse
Shape
: -
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()
. Um unterschiedliche Implementierungen der Methode zu erhalten draw()
, müssen wir für jede einer Farbe entsprechende Form eine Klasse erstellen. Wenn es drei Farben gibt, dann gibt es sechs Klassen: TriangleBlack
, TriangleGreen
, TriangleRed
, und . Sechs Unterrichtsstunden sind keine so große Sache. 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 Ausprobieren von Optionen über Bedingungen ist nicht die beste Lösung. Eine gute Lösung besteht darin, Farben in einer separaten Oberfläche anzuzeigen . Gesagt, getan: Erstellen wir eine Schnittstelle und drei ihrer Implementierungen – und : RectangleBlack
RectangleGreen
RectangleRed
Color
BlackColor
GreenColor
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"); } }
Color
Fügen wir nun der Klasse ein Typfeld hinzuShape
– 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(); }
color
Wir werden die Variable in Implementierungen verwendenShape
. Dies bedeutet, dass Shapes nun die Funktionalität der Schnittstelle nutzen könnenColor
. -
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 color
ist eine Brücke, die zwei separate Klassenhierarchien miteinander verbindet.
Brückengerät: Was ist Abstraktion und Implementierung?
Werfen wir einen Blick auf das Klassendiagramm, das das Bridge-Muster beschreibt: 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 ist es:- Abstraktion - Klasse
Shape
; - RefinedAbstraction - Klassen
Triangle
,Rectangle
; - Implementor-Schnittstelle
Color
; - ConcreteImplementor -Klassen
BlackColor
undGreenColor
.RedColor
Shape
stellt eine Abstraktion dar – einen Mechanismus zur Steuerung der Einfärbung von Formen in verschiedenen Farben, der die Implementierung an die Schnittstelle delegiert Color
. Klassen Triangle
sind Rectangle
reale Objekte, die den von der Klasse angebotenen Mechanismus nutzen Shape
. BlackColor
und GreenColor
– RedColor
spezifische Implementierungen im Implementierungszweig. Sie werden oft als Plattform bezeichnet.
Wo wird das Bridge-Muster verwendet?
Ein großer Vorteil dieses Musters besteht darin, dass Sie Änderungen an der Funktionalität von Klassen in einem Zweig vornehmen können, ohne die Logik eines anderen Zweigs zu beeinträchtigen. Dieser Ansatz trägt auch dazu bei, die Kopplung von Programmklassen zu reduzieren. Die wichtigste Voraussetzung für die Verwendung von Mustern besteht darin, „den Anweisungen zu folgen“: Kleben Sie sie nirgendwo auf! Lassen Sie uns herausfinden, in welchen Fällen Sie Bridge unbedingt verwenden müssen:-
Wenn es notwendig ist, die Anzahl der Elemente in zwei Richtungen zu erweitern (geometrische Formen, Farben).
-
Wenn Sie eine große Klasse, die das Prinzip der Einzelverantwortung nicht erfüllt, in kleinere Klassen mit schmaler Profilfunktionalität aufteilen möchten.
-
Wenn möglicherweise Änderungen an der Betriebslogik bestimmter Entitäten erforderlich sind, während das Programm ausgeführt wird.
-
Verstecken Sie bei Bedarf die Implementierung vor Klassen-(Bibliotheks-)Clients.
Vor- und Nachteile des Musters
Wie andere Muster hat auch die Bridge sowohl Vor- als auch Nachteile. Vorteile von Bridge:- 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.
- Reduziert die Anzahl der Unterklassen – funktioniert, wenn die Anzahl der Entitäten in zwei Richtungen erweitert werden muss (z. B. die Anzahl der Formen und die Anzahl der Farben).
- Ermöglicht die getrennte Arbeit an zwei unabhängigen Zweigen der Abstraktion und Implementierung – dies kann von zwei verschiedenen Entwicklern durchgeführt werden, ohne sich in die Details des Codes des anderen zu vertiefen.
- Reduzierung der Klassenkopplung – der einzige Ort, an dem zwei Klassen verbunden sind, ist die Brücke (Feld
Color color
).
- Abhängig von der konkreten Situation und der Struktur des Gesamtprojekts kann es zu negativen Auswirkungen auf die Programmproduktivität kommen (z. B. wenn mehr Objekte initialisiert werden müssen).
- Erschwert die Lesbarkeit des Codes, da zwischen Klassen navigiert werden muss.
GO TO FULL VERSION