JavaRush /Java-Blog /Random-DE /Brückenentwurfsmuster

Brückenentwurfsmuster

Veröffentlicht in der Gruppe Random-DE
Hallo! Wir verstehen weiterhin ein weitreichendes und sehr nützliches Thema – Designmuster. Heute sprechen wir über Bridge. Wie andere Muster dient Bridge dazu, häufige Probleme zu lösen, mit denen ein Entwickler beim Entwurf einer Softwarearchitektur konfrontiert ist. Lassen Sie uns heute seine Funktionen studieren und herausfinden, wie man es verwendet.

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 Klasse Shape, 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");
       }
    }
Alles sieht einfach aus, bis wir das Konzept der „Farbe“ einführen. Das heißt, jede Figur hat ihre eigene Farbe, von der die Funktionalität der Methode abhängt 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 : RectangleBlackRectangleGreenRectangleRedColorBlackColorGreenColorRedColor
  • 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");
       }
    }

    ColorFügen wir nun der Klasse ein Typfeld hinzu Shape– 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();
    }

    colorWir werden die Variable in Implementierungen verwenden Shape. Dies bedeutet, dass Shapes nun die Funktionalität der Schnittstelle nutzen können Color.

  • Rechteck.java

    public class Rectangle extends Shape {
    
       public Rectangle(Color color) {
           super(color);
       }
    
       @Override
       public void draw() {
           System.out.println("Drawing rectangle");
           color.fillColor();
       }
    }
Bitte schön! Jetzt können wir sogar bis ins Unendliche verschiedene Farben und geometrische Formen erzeugen, wodurch die Anzahl der Klassen in der arithmetischen Progression erhöht wird. Das Feld Color colorist 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: Einführung in das Bridge-Entwurfsmuster – 2Hier 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 BlackColorund GreenColor.RedColor
Die Klasse Shapestellt eine Abstraktion dar – einen Mechanismus zur Steuerung der Einfärbung von Formen in verschiedenen Farben, der die Implementierung an die Schnittstelle delegiert Color. Klassen Trianglesind Rectanglereale Objekte, die den von der Klasse angebotenen Mechanismus nutzen Shape. BlackColorund GreenColorRedColorspezifische 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:
  1. Wenn es notwendig ist, die Anzahl der Elemente in zwei Richtungen zu erweitern (geometrische Formen, Farben).

  2. Wenn Sie eine große Klasse, die das Prinzip der Einzelverantwortung nicht erfüllt, in kleinere Klassen mit schmaler Profilfunktionalität aufteilen möchten.

  3. Wenn möglicherweise Änderungen an der Betriebslogik bestimmter Entitäten erforderlich sind, während das Programm ausgeführt wird.

  4. Verstecken Sie bei Bedarf die Implementierung vor Klassen-(Bibliotheks-)Clients.

Wenn Sie jedes Mal ein Muster verwenden, müssen Sie bedenken, dass es dem Code zusätzliche Elemente hinzufügt – es ist nicht ganz logisch, es in einem Projekt zu verwenden, in dem es nur eine geometrische Figur und eine oder zwei mögliche Farben gibt.

Vor- und Nachteile des Musters

Wie andere Muster hat auch die Bridge sowohl Vor- als auch Nachteile. Vorteile von Bridge:
  1. 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.
  2. 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).
  3. 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.
  4. Reduzierung der Klassenkopplung – der einzige Ort, an dem zwei Klassen verbunden sind, ist die Brücke (Feld Color color).
Nachteile von Bridge:
  1. 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).
  2. Erschwert die Lesbarkeit des Codes, da zwischen Klassen navigiert werden muss.

Unterschied zum Strategiemuster

Das Brückenmuster wird oft mit einem anderen Entwurfsmuster, der Strategie, verwechselt. Beide verwenden Komposition (im Beispiel für Formen und Farben haben wir Aggregation verwendet, aber das Brückenmuster kann auch Komposition verwenden), indem sie die Arbeit an andere Objekte delegieren. Aber es gibt einen Unterschied zwischen ihnen, und er ist riesig. Das Strategiemuster ist ein Verhaltensmuster: Es löst ganz andere Probleme. Die Strategie ermöglicht die Austauschbarkeit von Algorithmen, während Bridge die Abstraktion von der Implementierung trennt, um die Wahl zwischen verschiedenen Implementierungen zu ermöglichen. Das heißt, Bridge gilt im Gegensatz zu Strategy für ganze Konstrukte oder hierarchische Strukturen. Das Bridge-Muster kann eine gute Waffe im Arsenal eines Entwicklers sein; die Hauptsache ist, Situationen zu finden, in denen es sich lohnt, es einzusetzen, oder ein anderes Muster zu verwenden. Wenn Sie mit anderen Vorlagen noch nicht vertraut sind, lesen Sie diese Materialien:
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION