Wzorzec projektowy Strategy (strategia)

Moim drugim ulubionym (po Proxy) wzorcem projektowym jest strategia. Jako, że w większości jego opisów w internecie jest dość abstrakcyjna, postanowiłem przedstawić żywy przykład.

Pewnie robiąc jakieś PHP-owe aplikacje dla biznesu spotkaliście się z potrzebą tworzenia raportów i wykresów. Zwykle były one stałe i pre definiowane. Pisaliście klasę która miała albo osobną metodę dla każdego raportu albo jedna metodę wejściową typu ‚pobierzRaport($nazwa)’ i tam jeden wielki switch.

Nie trudno wymyślić, że nie jest to zbyt elastyczne rozwiązanie. Objętość klasy bardzo nam rośnie przy każdym dodaniu nowego typu raportu i generalnie kod staje się trudnym do utrzymania.

Jest na to rozwiązanie. Definiujemy sobie interfejs IReport:

interface IReport {
    public function getReportData(array $params);
}

Każdy nowy raport będzie implementował ten interfejs i będzie osobną klasą której plik umieścimy np w katalogu application/reports

Zakładając, że nasza aplikacja będzie pisana w jakimś modnym MVC frameworku, kontroler będzie wyglądał tak:

class IndexController extends Some_Cool_Framework_Controller { 

    public function reportAction(){
        if($this->_request->isPost()){
              $oModel = new SomeModel();
              $this->_view->reportData = $oModel->getReport($this->_request->getPost());
        }
   }
}

Natomiast model tak:

class SomeModel {
    //... jakies rozne ciekawe metody ...
    public function getReport(array $data){
        $oReportObject = new $data['report_name'];
        return $oReportObject->getReportData($data['params']);
    }
}

W ten sposób nie będziemy dla każdego nowego raportu dokładać do klasy modelu następnej metody czy kolejnego case’a w switchu. Wystarczy stworzyć dowolną klasę która będzie implementować interfejs IReport i dodać ją do wcześniej wspomnianego katalogu.

Oczywiście powyższy przykład jest przykładem naiwnym i należało by dodać do niego filtrowanie danych z post-a.

W oryginalnym rozwiązaniu, lista raportów wraz z nazwami klas raportowych była przechowywana w bazie danych, gdzie przez panel administracyjny można było nimi wygodnie zarządzać.

  1. becia pisze:

    skoro piszesz o wzorcu Stategy to pewnie pojawi się i wpis o State (czekam :] ) bo mega dużo podobieństwa w strukturze – nie no w sumie mają identyczną strukturę, jedynie jedna ale diametralna różnica, dzięki której mamy dwa a nie jeden wzorzec :) faktycznie w necie większość przykładów jest abstrakcyjnych, soku ten wpis daje rade w ogarnięciu idei imho :)

  2. Wojciech Soczyński pisze:

    Hm słyszałem o tym wzorcu, ale że nigdy nie przydał mi się nigdzie, więc pewnie nie napisze, dopóki nie będę miał jakiegoś własnego przykładu :>. Szczerze mówiąc to większość paternów sam wymyślam a potem szukam jak się nazywają 😉

  3. Rodzyn pisze:

    Bo Ty taka mądra jesteś Wojciech. 😀
    Ale weź coś zrób z tymi encjami bo jak dasz jakiś większy kawałek kodu to to kompletnie nieczytelne będzie. A jak będzie nieczytelne to nikomu się nie będzie chciało czytać 😛

  4. Wojciech Soczyński pisze:

    No dobra przyhakuje coś 😛

  5. Alan Gabriel Bem pisze:

    Warto nadmienić, że wzorzec strategii w projektach DDD nazywany bywa „Polisą”.

  1. There are no trackbacks for this post yet.

Leave a Reply

Informuj mnie o odpowiedziach poprzez e-mail. Możesz również subskrybować wpis bez zostawiania komentarza.