Cos'è il modello Bridge?
Il modello Bridge è un modello di progettazione strutturale. Cioè, il suo compito principale è creare una struttura completa di classi e oggetti. Bridge risolve questo problema separando una o più classi in gerarchie separate: astrazione e implementazione . Un cambiamento nella funzionalità in una gerarchia non comporta cambiamenti in un'altra. Tutto sembra chiaro, ma in realtà questa definizione suona molto ampia e non risponde alla domanda principale: “Cos’è il pattern Bridge?” Penso che sarà più facile per te capirlo nella pratica. Modelliamo subito un classico esempio per il pattern Bridge. Abbiamo una classe astrattaShape
che descrive generalmente una figura geometrica:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
Quando decidiamo di aggiungere forme triangolari e rettangolari, erediteremo dalla classe
Shape
: -
Rettangolo.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Triangolo.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
. Per avere diverse implementazioni del metodo draw()
, dobbiamo creare una classe per ogni forma corrispondente ad un colore. Se ci sono tre colori, allora ci sono sei classi: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
e RectangleRed
. Sei lezioni non sono un grosso problema. Ma! Se dobbiamo aggiungere una nuova forma o colore, il numero di classi aumenterà in modo esponenziale. Come uscire da questa situazione? Memorizzare i colori in un campo e provare le opzioni tramite i condizionali non è la soluzione migliore. Una buona soluzione è visualizzare i colori in un'interfaccia separata . Detto fatto: creiamo un'interfaccia Color
e tre delle sue implementazioni - BlackColor
, GreenColor
e RedColor
:
-
Colore.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"); } }
Ora aggiungiamo un campo di tipo
Color
alla classeShape
: riceveremo il suo valore nel costruttore. -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
color
Utilizzeremo la variabile nelle implementazioniShape
. Ciò significa che le forme ora possono utilizzare la funzionalità dell'interfacciaColor
. -
Rettangolo.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
è un ponte che collega due gerarchie di classi separate.
Dispositivo bridge: cos'è l'astrazione e l'implementazione
Diamo un'occhiata al diagramma delle classi che descrive il pattern Bridge: qui puoi vedere due strutture indipendenti che possono essere modificate senza compromettere la funzionalità dell'altra. Nel nostro caso è:- Classe di astrazione
Shape
; - Astrazione raffinata - classi
Triangle
,;Rectangle
- Implementatore - interfaccia
Color
; - ConcreteImplementor -
BlackColor
classiGreenColor
eRedColor
.
Shape
rappresenta un'astrazione, un meccanismo per controllare la colorazione delle forme in diversi colori, che delega l'implementazione all'interfaccia Color
. Le classi Triangle
sono Rectangle
oggetti reali che utilizzano il meccanismo offerto dalla classe Shape
. BlackColor
e GreenColor
- RedColor
implementazioni specifiche nel ramo Implementazione. Sono spesso chiamati piattaforma.
Dove viene utilizzato il modello Bridge?
Un enorme vantaggio nell'usare questo modello è che puoi apportare modifiche alla funzionalità delle classi in un ramo senza interrompere la logica di un altro. Questo approccio aiuta anche a ridurre l'accoppiamento delle classi di programma. La condizione principale per utilizzare i cartamodelli è “seguire le istruzioni”: non attaccarli da nessuna parte! In realtà, scopriamo in quali casi è assolutamente necessario utilizzare Bridge:-
Se è necessario espandere il numero di entità in due direzioni (forme geometriche, colori).
-
Se si desidera dividere una classe di grandi dimensioni che non soddisfa il principio di responsabilità unica in classi più piccole con funzionalità a profilo ristretto.
-
Se è possibile apportare modifiche alla logica di funzionamento di determinate entità mentre il programma è in esecuzione.
-
Se necessario, nascondere l'implementazione ai client di classe (libreria).
Pro e contro del modello
Come altri modelli, il Bridge presenta sia vantaggi che svantaggi. Vantaggi del ponte:- Migliora la scalabilità del codice: puoi aggiungere funzionalità senza timore di rompere qualcosa in un'altra parte del programma.
- Riduce il numero di sottoclassi: funziona quando è necessario espandere il numero di entità in due direzioni (ad esempio, il numero di forme e il numero di colori).
- Rende possibile lavorare separatamente su due rami indipendenti di Astrazione e Implementazione: questo può essere fatto da due diversi sviluppatori senza approfondire i dettagli del codice dell'altro.
- Ridurre l'accoppiamento delle classi: l'unico posto in cui due classi sono collegate è il bridge (campo
Color color
).
- A seconda della situazione specifica e della struttura del progetto nel suo insieme, potrebbe esserci un impatto negativo sulla produttività del programma (ad esempio, se è necessario inizializzare più oggetti).
- Complica la leggibilità del codice a causa della necessità di spostarsi tra le classi.
GO TO FULL VERSION