Adapter
Situace
V systému existuje nevyhovující třída se zastaralým, nekompatibilním,
nebo jinak neuspokojivým rozhraním. Funkcionalita existující třídy má
být zachována a pouze s minimálním úsilím převedena pod rozhraní nové.
Může se objevit i požadavek, aby se stávající třída již neměnila (a
někdy to ani není možné, například při použití knihovny).
Problém
Použití nevyhovující třídy ovlivňuje ta místa v systému, kde je
využívána její funkcionalita. Nevyhovující ůže do zbytku systému
zanést zbytečný zmatek, který bude navíc umocněn tím, že se zastaralá
třída časem odstraní úplně. a navíc se spolu s ním může šířit
nedokonalosti, které byly již identifikovány a odstraněny.
Přímá úprava zastaralé třídy by zabrala mnoho času a pokud je již
důkladně otestována, není k tomu zpravidla ani vůle. Přesto je ale
nutné, aby zbytek systému využíval již rozhraní nové.
Řešení
Nevyhovující třídu lze od zbytku systému odstínit tak, že se celá
zapouzdří do třídy nové. Tato třída již implementuje nové rozhraní a
poskytuje infrastrukturu pro transformaci požadavků od klienta na
příslušné metody zapouzdřené třídy.
Návrhový vzor Adapter se často používá jen jako dočasné řešení do
doby, než je nevyhovující třída nahrazena. Toto nahrazení je navíc
snadnější, protože zbytek systému je na nové rozhraní připraven. Další
častou aplikací tohoto návrhového vzoru je zajištění zpětné
kompatibility.
Varianty
- třídní adaptér – dědí od nevyhovující
třídy
- objektový adaptér – využívá delegaci
UML diagramy
Související vzory
- Facade – pro několik
tříd vytváří zcela nové rozhraní
- Iterator – adaptér
specializovaný na sekvenční procházení
- Proxy – má stejné
rozhraní jako zapouzdřena třída
Příklad
Následuje jednoduchý příklad implementace tohoto vzoru v programovacím jazyce Java.
Požadovaná funkcionalita
kód v jazyce Java - Zobrazit
-
/**
-
* Rozhraní specifikující
požadovanou funkcionalitu.
-
*
-
* @author Vojtěch
Hordějčuk
-
*/
-
public interface Target
-
{
-
/**
-
* Provede
požadavek.
-
*/
-
public void newRequest();
-
}
Nevyhovující třída
kód v jazyce Java - Zobrazit
-
/**
-
* Vnořená třída, která má
zpravidla zastaralé, nekompatibilní, nebo jinak
-
* nevyhovujícím rozhraní. Proto
k ní bude vytvořen odpovídající adaptér.
-
*
-
* @author Vojtěch
Hordějčuk
-
*/
-
public class
Adaptee
-
{
-
/**
-
* Provede
požadavek.
-
*/
-
public void oldRequest()
-
{
-
// ...
-
}
-
}
Adaptér nevyhovující třídy
kód v jazyce Java - Zobrazit
-
/**
-
* Adaptér, který implementuje
funkcionalitu požadovanou rozhraním "Target" a to
-
* tak, že přeposílá (deleguje)
požadavky třídě vnořené. K tomu může přidat
-
* nějakou řídící logiku.
Okolí nemusí vědět ani o instanci vnořené třídy, ani o
-
* způsobu, jakým se požadavky
převádí.
-
*
-
* @author Vojtěch
Hordějčuk
-
*/
-
public class
Adapter implements Target
-
{
-
/**
-
* vnořená
třída
-
*/
-
private Adaptee adaptee;
-
-
/**
-
* Vytvoří novou
instanci.
-
*/
-
public Adapter()
-
{
-
// vytvořit instanci
adaptované třídy
-
// (instance může být
předána i jinak, například parametrem)
-
-
this.adaptee = new Adaptee();
-
}
-
-
@Override
-
public void newRequest()
-
{
-
// v této ukázce se volání
pouze jednoduše deleguje
-
// (adaptér ale může přidat
nějakou řídící logiku navíc)
-
-
this.adaptee.oldRequest();
-
}
-
}
Test
kód v jazyce Java - Zobrazit
-
public static
void main(String[] args)
-
{
-
// vytvořit instanci třídy s
požadovanou funkcionalitou
-
-
Target adapter = new Adapter();
-
-
// provést požadavek
-
-
adapter.newRequest();
-
}
Reference