Hva er bromønsteret?
Bromønsteret er et strukturelt designmønster. Med andre ord er hovedoppgaven å skape en fullverdig struktur av klasser og objekter. En bro gjør dette ved å dele en eller flere klasser inn i separate hierarkier: abstraksjon og implementering . En endring i funksjonalitet i det ene hierarkiet medfører ikke en endring i det andre. Det er bra og greit, men denne definisjonen er veldig bred og svarer ikke på det viktigste spørsmålet: "Hva er bromønsteret?" Jeg tror det vil være lettere for deg å forstå den praktiske anvendelsen. Så med en gang, la oss lage et klassisk scenario for bromønsteret. Vi har en abstraktShape
klasse, som representerer en generisk geometrisk figur:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
Når vi bestemmer oss for å legge til figurer som trekanter og rektangler, vil vi få dem til å 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 avhenge av denne fargen. For å ha forskjellige implementeringer av draw()
metoden, må vi lage en klasse for hver form-fargekombinasjon. Hvis vi har tre farger, trenger vi seks klasser: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
og RectangleRed
. Seks klasser er ikke et så stort problem. Men! Hvis vi trenger å legge til en ny form eller farge, vokser antallet klasser eksponentielt. Hvordan komme seg ut av denne situasjonen? Å lagre farge i et felt og telle opp alle alternativene ved hjelp av betingede utsagn er ikke den beste løsningen. En god løsning er å flytte farge til et eget grensesnitt. Ikke før sagt enn gjort: la oss lage et Color
grensesnitt 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"); } }
Nå legger vi til et
Color
felt iShape
klassen. Vi får dens verdi 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 bruke
color
variabelen iShape
implementeringer. Dette betyr at former nå kan bruke funksjonaliteten til grensesnittetColor
. -
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 som forbinder to separate klassehierarkier.
Hvordan bygge en bro: abstraksjon og implementering
La oss se på et klassediagram som viser bromønsteret:
- Abstraksjon er
Shape
klassen - RefinedAbstraction er
Triangle
ogRectangle
klasser - Implementator er
Color
grensesnittet - ConcreteImplementor er
BlackColor
,GreenColor
ogRedColor
klassene.
Shape
er en abstraksjon - en mekanisme for å administrere fyllingen av former med forskjellige farger, som delegerer til grensesnittet Color
(Implementor). Klassene Triangle
og Rectangle
er konkrete klasser som bruker mekanismen som er gjort tilgjengelig av Shape
klassen. BlackColor
, GreenColor
og RedColor
er konkrete implementeringer i implementeringshierarkiet.
Hvor skal man bruke bromønsteret
En stor fordel med å bruke dette mønsteret er at du kan gjøre endringer i funksjonsklassene i ett hierarki uten å bryte logikken til det andre. Denne tilnærmingen bidrar også til å redusere kobling mellom klasser. Hovedkravet når du bruker dette mønsteret er "følg instruksjonene" - ikke ignorer noen av dem! For det formål, la oss finne ut situasjonene når du definitivt bør bruke bromønsteret:-
Hvis du trenger å utvide antall enheter basert på kombinasjoner av to konsepter (f.eks. former og farger).
-
Hvis du ønsker å dele en stor klasse som ikke oppfyller enkeltansvarsprinsippet i mindre klasser som har snever funksjonalitet.
-
Hvis det er nødvendig å gjøre endringer i logikken til visse enheter mens programmet kjører.
-
Hvis det er nødvendig å skjule en implementering fra klientene til klassen eller biblioteket.
Fordeler og ulemper med mønsteret
Som andre mønstre har en bro både fordeler og ulemper. Fordeler med bromønsteret:- Det forbedrer skalerbarheten til kode - du kan legge til funksjonalitet uten frykt for å ødelegge noe i en annen del av programmet.
- Det reduserer antall underklasser når antallet enheter ellers ville vært basert på kombinasjoner av to konsepter (for eksempel former og farger).
- Det gjør det mulig å arbeide separat på to separate hierarkier — Abstraksjon og Implementering. To forskjellige utviklere kan gjøre endringer uten å fordype seg i detaljene i hverandres kode.
- Det reduserer koblingen mellom klasser - det eneste stedet hvor de to klassene er koblet er broen (dvs. feltet
Color color
).
- Avhengig av den spesifikke situasjonen og den generelle strukturen til et prosjekt, kan det påvirke ytelsen til et program negativt (for eksempel hvis du trenger å initialisere flere objekter).
- Det gjør koden mindre lesbar på grunn av behovet for å bytte mellom de to klassene.
GO TO FULL VERSION