29 maja 2020

Wzorce projektowe: Fabryka

Wzorzec projektowy który myślę, że większość z nas używała jeszcze nim go poznała 🙂

Wzorzec „Factory” nie jest niczym skomplikowanym. Programując na pewno nie raz go wykorzystałeś, nie potrafiąc go nazwać.

Wykorzystanie Fabryki

Fabryka, jest wykorzystywana wszędzie tam, gdzie chcemy aby konkretyzacja tworzenia obiektu była odseparowana od kodu który operuje na abstrakcjach. Więc klasa specjalizująca może decydować o konkretnych obiektach, my zaś będziemy operowali na interfejsach bądź klasach abstrakcyjnych.

Poniższy przykład wyjaśni wszystko:

Przykład

Tworzymy stronę internetową, strona zostanie wyposażona w kilka typów podstron np:

  1. Galeria
  2. Kontakt
  3. Tekstowa
  4. Ofertowa

Każdy typ podstrony, będzie obsługiwała inna specjalizująca się w tym celu klasa. Może to wyglądać w dużym uproszczeniu tak:

class TextPage extends Page
{

}

class ContactPage extends Page
{

}

class GalleryPage extends Page
{

}

class OfferPage extends Page
{

}

Oraz klasa z której dziedziczyć będą powyższe klasy:

abstract class Page
{
    public function render() {
        ...
    }
}

W klasie abstrakcyjnej możemy umieścić np. metody odpowiedzialne za renderowanie wspólnych elementów, przykładowo „footer” lub „header„.

Zajmijmy się wreszcie samą fabryką.

class FactoryPage
{
    private $pageClass;

    public function __construct(string $page)
    {
        switch ($page) {
            case 'text':
                $this->pageClass = new TextPage();
                break;
            case 'contact':
                $this->pageClass = new ContactPage();
                break;
            case 'gallery':
                $this->pageClass = new GalleryPage();
                break;
            case 'offer':
                $this->pageClass = new OfferPage();
                break;
        }
    }
    public function render()
    {
        return $this->pageClass->render();
    }
}

Powyższy przykład pokazuje właśnie sposób w jaki działają fabryki.

Niestety switch nie jest świetnym rozwiązaniem, ale gdzieś trzeba w końcu podjąć decyzję o tym, którą klasę potrzebujemy w danym momencie. Decyzja ta najlepiej aby była podjęta raz i nie wymagała duplikowania w kodzie.

Kod kliencki będzie wyglądał mniej więcej tak:

$contactPage = new FactoryPage('contact');
$contactPage->render();

Podsumowanie

Fabrykę możemy stosować w sytuacji, w której chcemy pozostać poza warstwą konkretyzacji obiektów. Gdy nasz program posiada dane, ale na tym etapie nie chcemy wykonać sprawdzenia danych i na podstawie ich dobrać odpowiednie obiekty, możemy ten obowiązek zrzucić do osobnej klasy którą jest właśnie fabryka.