Project Technical Lead
Návrhové vzory Java (design patterns): Adaptér
Dnes sa pozrieme na prvý návrhový vzor Adaptér (java design patterns) z kategórie štrukturálnych vzorov (structural patterns). Návrhové vzory v tejto kategórii sa zaoberajú štruktúrou triedy, ako je dedičnosť (inheritance) a kompozícia (composition).
Prečítaj si o ďalších design patterns – seriál návrhových vzorov:
- Design pattern Singleton
- Design pattern Builder
- Design pattern Prototype
- Design pattern Factory
- Design pattern Abstract factory
Čo to je Adapter design pattern?
Adaptér je návrhový vzor, ktorý umožňuje komunikáciu medzi dvomi existujúcimi triedami alebo rozhraniami, ktoré nemôžu spolu komunikovať kvôli nekompatibilite ich rozhraní. Adaptér umožňuje týmto nekompatibilným častiam spolupracovať tým, že poskytuje sprostredkované rozhranie.
Aký problém rieši Adapter design pattern?
Adaptér teda rieši problém komunikácie medzi nekompatibilnými časťami komponentov a to tak, že vytvorí medzivrstvu medzi nimi a prevádza volania medzi rozhraniami. Adaptér je užitočný, keď potrebujeme integrovať existujúci kód alebo triedy s novým kódom, ktorý očakáva iné rozhranie. Namiesto toho, aby sme menili kód existujúcich tried, môžeme vytvoriť adaptér, ktorý bude sprostredkovať komunikáciu.
S týmto návrhovým vzorom sa môžeme stretnúť aj v jazyku Java a to pri práci s tzv. obaľovacími (wrapper) triedami. Wrapper triedy vytvoria objektové typy z primitívnych dátových typov tak, že sa zabalia do adaptéru, ktorý potom implementuje požadované vlastnosti objektového typu. To má potom za následok, že môžeme pracovať s inštanciou triedy Integer, podobne ako by sme pracovali s obyčajnou premennou typu int.
Príklad Adaptér implementácie v Jave
Teraz si ukážeme ako implementovať vzor Adaptér v Jave.
Používame rozhranie Tvar pre výpočet plochy ľubovoľného tvaru.
Tvar.java
package designpatterns;
public interface Tvar {
public int vypocitajObsah(int x);
}
Toto rozhranie používa aj implementácia triedy Stvorec.
Stvorec.java
package designpatterns;
// Aktuálna implementácia rozhrania Tvar
public class Stvorec implements Tvar {
@Override
public int vypocitajObsah(int x) {
return x * x;
}
}
Chceli by sme použiť aj externú implementáciu pre výpočet obsahu kruhu dodanú treťou stranou, táto však neimplementuje naše rozhranie Tvar, ktoré nemôžeme upraviť, pretože sa už používa.
Kruh.java
package designpatterns;
// Implementácia triedy Kruh dodaná externe cez knižnicu
public class Kruh {
public double vypocitajObsahKruhu(int r) {
return 3.14 * r * r;
}
}
Riešením je prispôsobenie implementácie Kruh nášmu rozhraniu Tvar. Potrebujeme teda adaptér, keďže metódy sú nekompatibilné.
KruhAdapter.java
package designpatterns;
public class KruhAdapter extends Kruh implements Tvar {
@Override
public int vypocitajObsah(int x) {
return (int) vypocitajObsahKruhu(x);
}
}
Main.java
Teraz už môžeme používať oba tvary Stvorec a Kruh (prostredníctvom adaptéra KruhAdapter) a zavolať na nich metódu na výpočet plochy.
import designpatterns.KruhAdapter;
import designpatterns.Stvorec;
import designpatterns.Tvar;
// Použitie vzoru adapter
public class Main {
public static void main(String[] args) {
Tvar kruh = new KruhAdapter();
System.out.println("Obsah kruhu: " + kruh.vypocitajObsah(4));
Tvar stvorec = new Stvorec();
System.out.println("Obsah štvorca: " + stvorec.vypocitajObsah(4));
}
}
Výstup z tohto príkladu je:
Zhrnutie
Návrhový vzor Adaptér sa používa v situácii, keď je potrebné, aby trieda mala iné rozhranie než to, ktoré práve má. Adaptér umožňuje spoluprácu triedam, ktoré by inak nespolupracovali vďaka rozdielnemu rozhraniu. Adaptér je možné vzhľadom na použitú implementáciu klasifikovať na adaptér triedy a adaptér objektu.
Pripravili sme pre teba súbory so spomínaným príkladom vo forme kódu, ktorý si môžeš spustiť priamo v Jave. Stiahni si kód Java Adaptér tu.