Care este modelul podului?
Modelul podului este un model de proiectare structurală. Cu alte cuvinte, sarcina sa principală este de a crea o structură cu drepturi depline din clase și obiecte. O punte face acest lucru împărțind una sau mai multe clase în ierarhii separate: abstractizare și implementare . O modificare a funcționalității într-o ierarhie nu implică o schimbare în cealaltă. Toate acestea sunt bune și bune, dar această definiție este foarte largă și nu răspunde la cea mai importantă întrebare: „Care este modelul podului?” Cred că vă va fi mai ușor să înțelegeți aplicarea sa practică. Deci, imediat, să creăm un scenariu clasic pentru modelul podului. Avem oShape
clasă abstractă, care reprezintă o figură geometrică generică:
-
Formă.java
public abstract class Shape { public abstract void draw(); }
Când decidem să adăugăm forme precum triunghiuri și dreptunghiuri, le vom face să moștenească
Shape
clasa: -
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()
va depinde de această culoare. Pentru a avea implementări diferite ale draw()
metodei, atunci trebuie să creăm o clasă pentru fiecare combinație formă-culoare. Dacă avem trei culori, atunci avem nevoie de șase clase: TriangleBlack
, TriangleGreen
, TriangleRed
, și . Șase clase nu este o problemă atât de mare. Dar! Dacă trebuie să adăugăm o nouă formă sau culoare, atunci numărul de clase crește exponențial. Cum să ieși din această situație? Stocarea culorii într-un câmp și enumerarea tuturor opțiunilor folosind instrucțiuni condiționale nu este cea mai bună soluție. O soluție bună este să mutați culoarea într-o interfață separatăRectangleBlack
RectangleGreen
RectangleRed
. Nu mai devreme de spus, de făcut: să creăm o Color
interfață cu trei implementări: și : BlackColor
GreenColor
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"); } }
Acum adăugăm un
Color
câmp laShape
clasă. Îi vom obține valoarea în constructor. -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
Vom folosi
color
variabila înShape
implementări. Aceasta înseamnă că formele pot folosi acum funcționalitatea interfețeiColor
. -
dreptunghi.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
este o punte care conectează două ierarhii de clasă separate.
Cum să construiești o punte: abstractizare și implementare
Să ne uităm la o diagramă de clasă care ilustrează modelul de punte: Aici puteți vedea două structuri independente care pot fi modificate fără a afecta funcționalitatea celuilalt. În cazul nostru:- Abstracția este
Shape
clasa - RefinedAbstraction este clasele
Triangle
șiRectangle
- Implementator este
Color
interfața - ConcreteImplementor este clasele
BlackColor
și .GreenColor
RedColor
Shape
este o abstractizare — un mecanism de gestionare a umplerii formelor cu diferite culori, care se deleagă la Color
interfață (Implementor). Clasele Triangle
și Rectangle
sunt clase concrete care folosesc mecanismul pus la dispoziție de Shape
clasă. BlackColor
, GreenColor
și RedColor
sunt implementări concrete în ierarhia de implementare.
Unde să folosiți modelul de punte
Un avantaj uriaș al utilizării acestui model este că puteți face modificări la clasele funcționale dintr-o ierarhie fără a rupe logica celeilalte. De asemenea, această abordare ajută la reducerea cuplării dintre clase. Principala cerință atunci când utilizați acest model este „urmați instrucțiunile” - nu ignorați niciunul dintre ele! În acest scop, să descoperim situațiile în care ar trebui să utilizați cu siguranță modelul de punte:-
Dacă trebuie să extindeți numărul de entități pe baza combinațiilor a două concepte (de exemplu, forme și culori).
-
Dacă doriți să împărțiți o clasă mare care nu îndeplinește principiul responsabilității unice în clase mai mici care au funcționalitate îngustă.
-
Dacă este necesar să faceți modificări în logica anumitor entități în timp ce programul rulează.
-
Dacă este necesar să ascundeți o implementare de clienții clasei sau bibliotecii.
Avantaje și dezavantaje ale modelului
Ca și alte modele, un pod are atât avantaje, cât și dezavantaje. Avantajele modelului de punte:- Îmbunătățește scalabilitatea codului - puteți adăuga funcționalitate fără teama de a sparge ceva într-o altă parte a programului.
- Reduce numărul de subclase atunci când numărul de entități s-ar baza altfel pe combinații a două concepte (de exemplu, forme și culori).
- Face posibilă lucrarea separată pe două ierarhii separate - Abstracție și Implementare. Doi dezvoltatori diferiți pot face modificări fără să intre în detaliile codului celuilalt.
- Reduce cuplarea dintre clase — singurul loc în care cele două clase sunt cuplate este puntea (adică câmpul
Color color
).
- În funcție de situația specifică și de structura generală a unui proiect, acesta ar putea avea un impact negativ asupra performanței unui program (de exemplu, dacă trebuie să inițializați mai multe obiecte).
- Face codul mai puțin lizibil din cauza necesității de a comuta între cele două clase.
GO TO FULL VERSION