Napisany sty-27-2009
wzorzec adapter
Cżesto mamy w domu jakiś kabel. Jednak korzystanie z niego jest niemożliwe, bez posiadania odpowiedniej przejściówki. W programowaniu obiektowym zdarzają się podobne sytuacje, ale na poziomie interfejsów. Czasami daną klasę musimy “przystosować” do warunków, w których będzie używana. Najłatwiej będzie to zrozumieć na prostym przykładzie. Załóżmy więc, że nad kodem naszej strony internetowej pracował jeden programista. W pewnym momencie zlecamy napisanie od nowa jednego komponentu innej osobie. Zobaczmy jego pracę:
// nowy komponent z nowym interfejsem
interface OutInterface {
public function XML() ;
public function PlainText();
public function RSS();
}
class Output implements OutInterface {
public function XML () {
echo 'XML';
}
public function PlainText () {
echo 'Plaintext';
}
public function RSS () {
echo 'RSS';
}
}
W czym tkwi problem? A no w tym, iż cała aplikacja korzysta z innego interfejsu, niż ten zaimplementowany w klasie Output:
// interfejs wykorzystywany w aplikacji
// dla starego komponentu Output
interface AppInterface {
public function WriteXML ();
public function WriteText ();
public function WriteRSS();
}
Co w tym wypadku zrobić? Bez sensu wydaje się jakakolwiek ingerencja w kod Output. Utworzymy dla niego adapter, z użyciem kompozycji. Spójrzmy:
// nowy komponent ze starym interfesjem
class OutputAdapter implements AppInterface {
private $adapter;
// korzystamy w konstruktorze z kompozycji
public function __construct (Output $obj) {
$this->adapter = $obj;
}
// uzywamy dobrze znanego interfejsu aplikacji, a tak naprawde
// wywolywane sa metody nowego komponentu
public function WriteXML () {
$this->adapter->XML();
}
public function WriteText () {
$this->adapter->PlainText();
}
public function WriteRSS () {
$this->adapter->RSS();
}
}
Zachęcam do korzystania z Wrapper’a (alternatywna nazwa), jak również z innych wzorców projektowych.
