CodeGym /Java blogg /Slumpmässig /Brodesignmönster
John Squirrels
Nivå
San Francisco

Brodesignmönster

Publicerad i gruppen
Hej! Vi fortsätter nu att fördjupa oss i ett omfattande och superviktigt användbart ämne: designmönster. Idag ska vi prata om bromönstret. Liksom andra mönster tjänar bromönstret till att lösa typiska problem som en utvecklare stöter på när han designar mjukvaruarkitektur. Låt oss idag studera funktionerna i detta mönster och ta reda på hur man använder det.

Vad är bromönstret?

Bromönstret är ett strukturellt designmönster. Med andra ord är dess huvudsakliga uppgift att skapa en fullfjädrad struktur av klasser och objekt. En brygga gör detta genom att dela upp en eller flera klasser i separata hierarkier: abstraktion och implementering . En förändring av funktionalitet i den ena hierarkin innebär inte en förändring i den andra. Det är bra och bra, men denna definition är väldigt bred och svarar inte på den viktigaste frågan: "Vad är bromönstret?" Jag tror att det blir lättare för dig att förstå dess praktiska tillämpning. Så direkt, låt oss skapa ett klassiskt scenario för bromönstret. Vi har en abstrakt Shapeklass, som representerar en generisk geometrisk figur:
  • Shape.java

    
    public abstract class Shape {
       public abstract void draw();
    }
    

    När vi bestämmer oss för att lägga till former som trianglar och rektanglar kommer vi att få dem att ärva 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");
       }
    }
    
Allt ser enkelt ut tills vi introducerar begreppet färg. Det vill säga att varje form kommer att ha sin egen färg, och metodens funktionalitet draw()kommer att bero på denna färg. För att ha olika implementeringar av draw()metoden måste vi skapa en klass för varje form-färgkombination. Om vi ​​har tre färger behöver vi sex klasser: TriangleBlack, TriangleGreen, TriangleRed, RectangleBlack, RectangleGreenoch RectangleRed. Sex klasser är inte ett så stort problem. Men! Om vi ​​behöver lägga till en ny form eller färg, så växer antalet klasser exponentiellt. Hur tar man sig ur denna situation? Att lagra färg i ett fält och räkna upp alla alternativ med villkorliga uttalanden är inte den bästa lösningen. En bra lösning är att flytta färg till ett separat gränssnitt. Inte tidigare sagt än gjort: låt oss skapa ett Colorgränssnitt med tre implementeringar: BlackColor, GreenColoroch 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 lägger vi till ett Colorfält i Shapeklassen. Vi får dess värde i konstruktören.

  • Shape.java:

    
    public abstract class Shape {
       protected Color color;
      
       public Shape(Color color) {
           this.color = color;
       }
    
       public abstract void draw();
    }
    

    Vi kommer att använda colorvariabeln i Shapeimplementeringar. ColorDet betyder att former nu kan använda gränssnittets funktionalitet .

  • Rectangle.java

    
    public class Rectangle extends Shape {
    
       public Rectangle(Color color) {
           super(color);
       }
    
       @Override
       public void draw() {
           System.out.println("Drawing rectangle");
           color.fillColor();
       }
    }
    
Ta-da! Nu kan vi skapa olika färger och former i det oändliga, och antalet klasser kommer bara att öka linjärt. Fältet Color colorär en bro som förbinder två separata klasshierarkier.

Hur man bygger en bro: abstraktion och implementering

Låt oss titta på ett klassdiagram som skildrar bromönstret: Introduktion av brodesignmönstret - 2Här kan du se två oberoende strukturer som kan modifieras utan att påverka varandras funktionalitet. I vårat fall:
  • Abstraktion är Shapeklassen
  • RefinedAbstraction är Triangleoch Rectangleklasserna
  • Implementator är Colorgränssnittet
  • ConcreteImplementor är , BlackColoroch GreenColorklasserna RedColor.
Klassen Shapeär en abstraktion — en mekanism för att hantera fyllningen av former med olika färger, som delegerar till gränssnittet ( ColorImplementor). Klasserna Triangleoch Rectangleär konkreta klasser som använder den mekanism som gjorts tillgänglig av Shapeklassen. BlackColor, GreenColoroch RedColorär konkreta implementeringar i implementeringshierarkin.

Var man använder bromönstret

En stor fördel med att använda detta mönster är att du kan göra ändringar i funktionsklasserna i en hierarki utan att bryta logiken i den andra. Detta tillvägagångssätt hjälper också till att minska kopplingen mellan klasser. Huvudkravet när du använder det här mönstret är "följ instruktionerna" - ignorera inte någon av dem! För det ändamålet, låt oss ta reda på situationerna när du definitivt bör använda bromönstret:
  1. Om du behöver utöka antalet enheter baserat på kombinationer av två begrepp (t.ex. former och färger).

  2. Om man vill dela upp en stor klass som inte uppfyller enansvarsprincipen i mindre klasser som har snäv funktionalitet.

  3. Om det är nödvändigt att göra ändringar i logiken för vissa enheter medan programmet körs.

  4. Om det är nödvändigt att dölja en implementering för klassens eller bibliotekets klienter.

När du använder det här mönstret, kom alltid ihåg att det lägger till ytterligare enheter till din kod - det kanske inte är meningsfullt att använda det i ett projekt där det bara finns en form och en eller två möjliga färger.

För- och nackdelar med mönstret

Liksom andra mönster har en bro både fördelar och nackdelar. Fördelar med bromönstret:
  1. Det förbättrar skalbarheten för koden - du kan lägga till funktionalitet utan rädsla för att gå sönder något i en annan del av programmet.
  2. Det minskar antalet underklasser när antalet entiteter annars skulle baseras på kombinationer av två begrepp (till exempel former och färger).
  3. Det gör det möjligt att separat arbeta på två separata hierarkier — Abstraktion och Implementering. Två olika utvecklare kan göra ändringar utan att fördjupa sig i detaljerna i varandras kod.
  4. Det minskar kopplingen mellan klasser — den enda platsen där de två klasserna är kopplade är bron (dvs. fältet) Color color.
Nackdelar med bromönstret:
  1. Beroende på den specifika situationen och den övergripande strukturen för ett projekt kan det påverka ett programs prestanda negativt (till exempel om du behöver initiera fler objekt).
  2. Det gör koden mindre läsbar på grund av behovet av att växla mellan de två klasserna.

Skillnad från strategimönstret

Bromönstret förväxlas ofta med ett annat designmönster — strategi. De använder båda komposition (även om vi använde aggregering i exemplet med figurer och färger, kan bromönstret också använda komposition), och delegerar arbete till andra objekt. Men det är skillnad på dem, och den är enorm. Strategimönstret är ett beteendemönster: det löser helt andra problem. Strategin gör att algoritmer kan utbytas, medan bridge separerar en abstraktion från implementeringar för att kunna välja mellan olika implementeringar. Med andra ord, till skillnad från en strategi, gäller en brygga hela enheter eller hierarkiska strukturer. Bromönstret kan vara ett bra vapen i en utvecklares arsenal. Det viktigaste är att identifiera de situationer där det är värt att använda det och känna igen när något annat mönster är lämpligt.
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION