bridge

Wpisem tym powracam do tematyki design patterns. Tym razem postaram się wyjaśnić czym jest bridge i w jakich okolicznościach jego użycie może się okazać niezbędne. Jeśli miałbym scharakteryzować most w jednym zdaniu, zapewne przybrałoby ono następującą formę:

Jest to wzorzec strukturalny, a jego głównym zadaniem jest oddzielenie implementacji od abstrakcji.

W tym lapidarnym stwierdzeniu ukryta jest esencja i ogromna moc tego wzorca. Aby go jednak w pełni zrozumieć, najlepiej będzie posłużyć się dwoma prostymi przykładami.

Przykład pierwszy – teoretyczny

Wyobraźmy sobie następującą sytuację. Chcemy stworzyć absolutnie perfekcyjne, pod każdym możliwym względem środowisko graficzne dla systemu operacyjnego. Oczywiście na rynku jest ogromna konkurencja. Każdy ma bowiem prawo stworzyć własny, idealny produkt. W kontekście poruszanego tematu mam na myśli autorską implementację ów środowiska, udostępnianego dla systemu operacyjnego – swego rodzaju klienta. Jak wiadomo cały czas pojawiają się nowsze wersje systemu, w których często wprowadzane są mniejsze lub większe modyfikacje. Aczkolwiek zdecydowana część pozostaje bez zmian. Zastosowanie mostu pomiędzy interfejsem środowiska graficznego a rdzeniem klienta, pozwala na odseparowanie ich od siebie, co niesie za sobą sporo korzyści. Łatwo zauważyć, że zarówno abstrakcja jak i implementacja mogą być rozwijane niezależnie. Poniższy rysunek obrazuje, to co starałem się wyżej wyjaśnić.

Przykład drugi – praktyczny

Na ten moment obraz wzorca wydawać się może być nieco mglisty i mało wyraźny. Dlatego też najprościej będzie go zaprezentować, dokonując prostej implementacji. Na starcie stwórzmy sobie interfejs środowiska graficznego:

// interfejs środowiska graficznego
interface Graphics
{

    public function Draw($string);
    public function Ln();
    public function Bold($string);

}
// implementacja srodowiska firmy A
class GraphicsA implements Graphics
{

    public function Draw ($string)
    {

        echo $string;

    }

    public function Ln ()
    {

        echo '';

    }

    public function Bold ($string)
    {

        echo '',$string,'';

    }

}

// implementacja srodowiska firmy B
class GraphicsB implements Graphics
{

    public function Draw ($string)
    {

        echo '',$string,'';

    }

    public function Ln ()
    {

        echo '


';

    }

    public function Bold ($string)
    {

        echo '',$string,'';

    }

}

Teraz czas na abstrakcję:

// abstrakcja rdzenia klienta
// uzywajacego srodowiska graficznego

abstract class System
{
    // MA srodowiska graficzne
    // implementujace interfejs
    // Graphics
    private $graphic;

    public function __construct (Graphics $graphics)
    {

        $this->graphic = $graphics;

    }

    // zwykly setter dla srodowiska
    public function SetGraphics(Graphics $interface)
    {

        $this->graphic = $interface;

    }

    public function Draw ($string)
    {

        $this->graphic->Draw($string);
        $this->graphic->Ln();

    }

    public function Bold ($string)
    {

        $this->graphic->Bold($string);
        $this->graphic->Ln();

    }

}

class MySystem extends System
{

    public function DrawSystemName ()
    {

        $this->Draw(__CLASS__);

    }    

}

class YourSystem extends System
{

    public function DrawMyNameBold ($name)
    {

        $this->Bold($name);

    }

}

Oraz wykorzystanie powyższego kodu:

$system = new MySystem(new GraphicsA ());
$system->DrawSystemName();
$system->SetGraphics(new GraphicsB ());
$system->DrawSystemName();

$systemB = new YourSystem(new GraphicsA ());
$systemB->DrawMyNameBold(__FILE__);
$systemB->SetGraphics(new GraphicsB ());
$systemB->DrawMyNameBold(__FILE__);

Pragnę zwrócić uwagę na fakt, iż zmiany w interfejsie graficznym nie przełożą się na modyfikacje w klasach rzeczywistych (których może być bardzo dużo!) dziedziczących po System, pod warunkiem hermetyzacji wywołań Graphics w obrębie ów klasy.
Jak zwykle zachęcam do eksperymentów i poszerzania wiedzy w obrębie nie tylko tego, ale również innych wzorców projektowych.

2 Odpowiedzi : “bridge”

  1. echo ‘‘,$string,’‘;
    zamienić wszędzie , na . ;) Bo inaczej będzie pluło errorami ;)

  2. RalF napisał:

    Hej! :)
    Echo może przyjmować , zamiast stosowania konkatenacji. O to Ci chodziło? (http://php.net/manual/en/function.echo.php)

Pozostaw Odpowiedź