Hvad er bromønsteret?
Bromønsteret er et strukturelt designmønster. Med andre ord er dens hovedopgave at skabe en fuldgyldig struktur ud af klasser og objekter. En bro gør dette ved at opdele en eller flere klasser i separate hierarkier: abstraktion og implementering . En ændring i funktionalitet i det ene hierarki medfører ikke en ændring i det andet. Det er alt sammen fint og godt, men denne definition er meget bred og besvarer ikke det vigtigste spørgsmål: "Hvad er bromønsteret?" Jeg tror, det vil være lettere for dig at forstå dens praktiske anvendelse. Så med det samme, lad os skabe et klassisk scenarie for bromønsteret. Vi har en abstraktShape
klasse, som repræsenterer en generisk geometrisk figur:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
Når vi beslutter os for at tilføje figurer som trekanter og rektangler, vil vi få dem til at arve klassen
Shape
: -
Rectangle.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()
vil afhænge af denne farve. For at have forskellige implementeringer af draw()
metoden, så skal vi oprette en klasse for hver form-farve kombination. Hvis vi har tre farver, har vi brug for seks klasser: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
og RectangleRed
. Seks klasser er ikke så stort et problem. Men! Hvis vi skal tilføje en ny form eller farve, så vokser antallet af klasser eksponentielt. Hvordan kommer man ud af denne situation? At gemme farve i et felt og opregne alle muligheder ved hjælp af betingede udsagn er ikke den bedste løsning. En god løsning er at flytte farve til en separat grænseflade. Ikke før sagt end gjort: lad os skabe en Color
grænseflade med tre implementeringer: BlackColor
, GreenColor
og RedColor
:
-
Color.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"); } }
Nu tilføjer vi et
Color
felt tilShape
klassen. Vi får dens værdi i konstruktøren. -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
Vi vil bruge
color
variablen iShape
implementeringer. Det betyder, at former nu kan bruge grænsefladens funktionalitetColor
. -
Rectangle.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
er en bro, der forbinder to separate klassehierarkier.
Hvordan man bygger en bro: abstraktion og implementering
Lad os se på et klassediagram, der afbilder bromønsteret:
- Abstraktion er
Shape
klassen - RefinedAbstraction er
Triangle
ogRectangle
klasserne - Implementer er
Color
grænsefladen - ConcreteImplementor er
BlackColor
,GreenColor
ogRedColor
klasserne.
Shape
er en abstraktion - en mekanisme til at styre udfyldningen af former med forskellige farver, som uddelegerer til grænsefladen Color
(Implementor). Klasserne Triangle
og Rectangle
er konkrete klasser, der bruger den mekanisme, som Shape
klassen har stillet til rådighed. BlackColor
, GreenColor
og RedColor
er konkrete implementeringer i implementeringshierarkiet.
Hvor skal man bruge bromønsteret
En stor fordel ved at bruge dette mønster er, at du kan foretage ændringer i de funktionelle klasser i det ene hierarki uden at bryde logikken i det andet. Denne tilgang hjælper også med at reducere kobling mellem klasser. Hovedkravet, når du bruger dette mønster, er "følg instruktionerne" - ignorer ikke nogen af dem! Til det formål, lad os finde ud af de situationer, hvor du helt sikkert bør bruge bromønsteret:-
Hvis du skal udvide antallet af entiteter baseret på kombinationer af to koncepter (f.eks. former og farver).
-
Hvis man vil opdele en stor klasse, der ikke opfylder enkeltansvarsprincippet, i mindre klasser, der har snæver funktionalitet.
-
Hvis det er nødvendigt at foretage ændringer i logikken for visse enheder, mens programmet kører.
-
Hvis det er nødvendigt at skjule en implementering for klassens eller bibliotekets klienter.
Fordele og ulemper ved mønsteret
Som andre mønstre har en bro både fordele og ulemper. Fordele ved bromønsteret:- Det forbedrer skalerbarheden af kode - du kan tilføje funktionalitet uden frygt for at bryde noget i en anden del af programmet.
- Det reducerer antallet af underklasser, når antallet af entiteter ellers ville være baseret på kombinationer af to begreber (f.eks. former og farver).
- Det gør det muligt at arbejde separat på to separate hierarkier — Abstraktion og Implementering. To forskellige udviklere kan foretage ændringer uden at dykke ned i detaljerne i hinandens kode.
- Det reducerer koblingen mellem klasser - det eneste sted, hvor de to klasser er koblet, er broen (dvs. feltet
Color color
).
- Afhængigt af den specifikke situation og den overordnede struktur af et projekt, kan det have en negativ indvirkning på et programs ydeevne (f.eks. hvis du skal initialisere flere objekter).
- Det gør koden mindre læsbar på grund af behovet for at skifte mellem de to klasser.
GO TO FULL VERSION