Wat is het brugpatroon?
Het brugpatroon is een structureel ontwerppatroon. Met andere woorden, zijn belangrijkste taak is het creëren van een volwaardige structuur uit klassen en objecten. Een bridge doet dit door een of meer klassen op te delen in afzonderlijke hiërarchieën: abstractie en implementatie . Een verandering in functionaliteit in de ene hiërarchie brengt geen verandering in de andere met zich mee. Dat is allemaal leuk en aardig, maar deze definitie is erg breed en geeft geen antwoord op de belangrijkste vraag: "Wat is het brugpatroon?" Ik denk dat het voor u gemakkelijker zal zijn om de praktische toepassing ervan te begrijpen. Laten we dus meteen een klassiek scenario maken voor het brugpatroon. We hebben een abstracteShape
klasse, die een generieke geometrische figuur vertegenwoordigt:
-
Vorm.java
public abstract class Shape { public abstract void draw(); }
Wanneer we besluiten om vormen zoals driehoeken en rechthoeken toe te voegen, laten we ze de
Shape
klasse erven: -
Rechthoek.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Driehoek.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
methode hangt af van deze kleur. Om verschillende implementaties van de draw()
methode te hebben, moeten we een klasse maken voor elke vorm-kleurcombinatie. Als we drie kleuren hebben, hebben we zes klassen nodig: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
en RectangleRed
. Zes klassen is niet zo'n groot probleem. Maar! Als we een nieuwe vorm of kleur moeten toevoegen, groeit het aantal klassen exponentieel. Hoe kom je uit deze situatie? Kleur opslaan in een veld en alle opties opsommen met behulp van voorwaardelijke instructies is niet de beste oplossing. Een goede oplossing is om kleur naar een aparte interface te verplaatsen. Zo gezegd, zo gedaan: laten we een Color
interface maken met drie implementaties: BlackColor
, GreenColor
en RedColor
:
-
Kleur.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 voegen we een
Color
veld toe aan deShape
klasse. We krijgen de waarde ervan in de constructor. -
Vorm.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
We zullen de
color
variabele gebruiken inShape
implementaties. Dit betekent dat vormen nu de functionaliteit van de interface kunnen gebruikenColor
. -
Rechthoek.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
veld is een brug die twee afzonderlijke klassenhiërarchieën met elkaar verbindt.
Hoe een brug te bouwen: abstractie en implementatie
Laten we eens kijken naar een klassendiagram dat het brugpatroon weergeeft:
- Abstractie is de
Shape
klasse - RefinedAbstraction is de klasse
Triangle
enRectangle
- Uitvoerder is de
Color
interface - ConcreteImplementor is de klasse
BlackColor
,GreenColor
enRedColor
.
Shape
klasse is een abstractie — een mechanisme voor het beheer van het vullen van vormen met verschillende kleuren, dat wordt gedelegeerd aan de Color
interface (Implementor). De klassen Triangle
en Rectangle
zijn concrete klassen die gebruikmaken van het mechanisme dat door de Shape
klasse beschikbaar wordt gesteld. BlackColor
, GreenColor
en RedColor
zijn concrete implementaties in de Implementatiehiërarchie.
Waar het brugpatroon te gebruiken
Een groot voordeel van het gebruik van dit patroon is dat u wijzigingen kunt aanbrengen in de functionele klassen in de ene hiërarchie zonder de logica van de andere te doorbreken. Deze aanpak helpt ook om de koppeling tussen klassen te verminderen. De belangrijkste vereiste bij het gebruik van dit patroon is "volg de instructies" - negeer ze niet! Laten we daarom de situaties uitzoeken waarin u zeker het brugpatroon moet gebruiken:-
Als u het aantal entiteiten wilt uitbreiden op basis van combinaties van twee concepten (bijvoorbeeld vormen en kleuren).
-
Als u een grote klasse die niet voldoet aan het principe van één verantwoordelijkheid wilt verdelen in kleinere klassen met beperkte functionaliteit.
-
Als het nodig is om wijzigingen aan te brengen in de logica van bepaalde entiteiten terwijl het programma draait.
-
Als het nodig is om een implementatie te verbergen voor de clients van de klas of bibliotheek.
Voors en tegens van het patroon
Net als andere patronen heeft een brug zowel voor- als nadelen. Voordelen van het brugpatroon:- Het verbetert de schaalbaarheid van code - u kunt functionaliteit toevoegen zonder bang te hoeven zijn iets in een ander deel van het programma kapot te maken.
- Het vermindert het aantal subklassen wanneer het aantal entiteiten anders gebaseerd zou zijn op combinaties van twee concepten (bijvoorbeeld vormen en kleuren).
- Het maakt het mogelijk om afzonderlijk aan twee afzonderlijke hiërarchieën te werken: abstractie en implementatie. Twee verschillende ontwikkelaars kunnen wijzigingen aanbrengen zonder zich te verdiepen in de details van elkaars code.
- Het vermindert de koppeling tussen klassen — de enige plaats waar de twee klassen zijn gekoppeld is de brug (dwz het
Color color
veld).
- Afhankelijk van de specifieke situatie en de algehele structuur van een project, kan dit een negatieve invloed hebben op de prestaties van een programma (bijvoorbeeld als u meer objecten moet initialiseren).
- Het maakt code minder leesbaar vanwege de noodzaak om tussen de twee klassen te schakelen.
GO TO FULL VERSION