Kaskadowe ładowanie klas

Kaskadowość większości ludzi związanymi z web developementem pewnie kojarzy się z kaskadowymi arkuszami styli (CSS). Jest to poniekąd słuszne skojarzenie, ponieważ daje pewne wyobrażenie czym ona jest.

W CSS-ach kaskadowość znaczy nie mniej, nie więcej tyle, że właściwości stylu zdefiniowane dla elementów wyżej w drzewie dokumentu propagują się w dół drzewa aż do momentu kiedy nie zostaną nadpisane przez właściwości elementów niżej w hierarchii.

W PHP istnieje technika oparta na podobnych założeniach, realizowana dzięki magicznej funkcji __autoload. Na czym więc polega ?

Załóżmy, że mamy pewną hierarchię klas:

--A

---B
----E

---C
----D
----E

Każda z tych klas dziedziczy bezpośrednio lub pośrednio z klasy A. Załóżmy teraz, że chcielibyśmy zmienić zachowanie wszystkich klas dziedziczących z A. Jednym z rozwiązań jest po prostu modyfikacja odpowiedniej metody z klasy A, jest to oczywiście najlepsze wyjście, z kilkoma wyjątkami, z których najpoważniejszym jest to, że klasa A należy do pewnej zewnętrznej biblioteki.

Klasycznym przykładem tego typu są formularze dziedziczące z Zend_Form. Mamy już gotowych n-bardzo dużo formularzy, jednak nagle okazało się, że trzeba im globalnie coś zmienić. Nie możemy za bardzo modyfikować samego Zend_Form-a ponieważ należy on do zewnętrznej biblioteki i w razie modyfikacji go, będzie problem z migracją do nowszych wersji frameworka.

Zmiana tych n-bardzo wielu klas, aby dziedziczyły z innej pośredniej klasy, która dziedziczy z Zend_Form będzie procesem bardzo pracochłonnym.

W tym momencie z pomocą przychodzi nam kaskadowość. Dzięki niej będziemy mogli podmienić oryginalną klasę Zend_Form, bez modyfikacji jej kodu.

Po pierwsze będzie nam potrzebna odpowiednia struktura katalogów:

-test_cascading
--base
---application
----forms
---library
----Zend
--modified
---library
----Zend

Naszą zmodyfikowaną klasę Zend_Form umieścimy w podkatalogu „modified” w takiej samej ścieżce jak w katalogu „base”.

Podczas ładowania naszych formularzy, które dziedziczą z Zend_Form, autoloader najpierw sprawdzi, czy istnieje plik z klasą w wersji zmodyfikowanej w katalogu „modified/library/Zend…” a gdy go nie ma, załaduje go z katalogu „base/library/Zend…”

Kod:

function __autoload($className){

$sPath = str_replace('_','/',$className).'.php';

$aCascade = array('modified/library','base/library');
foreach($aCascade as $branch){
    if(file_exists($branch.'/'.$sPath){
        require $branch.'/'.$sPath;
        return;
    }
}
}

Osobiście wykorzystuje kaskadowość również w innych celach. M.in gdy tworze w projekcie osobny branch na jakąś funkcjonalność, dokładam po prostu kolejny katalog w kaskadzie tylko z koniecznymi plikami, zamiast cały projekt branchować.

Na koniec jeszcze trzy słowa o wadach kaskadowości.

  • Po pierwsze, kaskadowość w pewnym stopniu spowalnia kod – więcej dostępów do dysku w zależności od długości kaskady. Dlatego w miarę możliwości należy jej używać tylko w środowisku developerskim.
  • Po drugie zbyt wiele plików w kaskadzie prowadzi do tego, że możemy się pogubić gdzie co w końcu było.

Jak widać więc, kaskadowe ładowanie klas jest mieczem obosiecznym i jak każdą rzecz należy stosować ją z umiarem.

P.S
z kaskadowości korzysta między innymi framework KOHANA.

  1. batman pisze:

    Jakoś mnie nie przekonałeś do tej idei. Zwłaszcza w kontekście ZF. Jeśli korzystam z rozwiązań, o których wiem, że będę je musiał rozszerzyć, pierwszą rzeczą jaką robię jest napisanie klasy (nawet pustej), która dziedziczy z klasy frameworka. Wówczas wspomniane nieprzewidziane modyfikacje wprowadzam w tej klasie. Oprócz dziedziczenia mamy jeszcze do dyspozycji kompozycję.

    Jakiś czas temu natknąłem się na implementację w PHP metod rozszerzeń z C# (extension methods), która pozwala na wstrzyknięcie do danego obiektu nowych metod. Niestety nie działa to zbyt szybko 😉

  2. Wojciech Soczyński pisze:

    Nie przekonuje nikogo do tej idei, po prostu ją przedstawiam, przydaje się w niektórych sytuacjach.

  3. Krzysiek pisze:

    Korzystam z kohany i uwazam ze wlasnie ta kaskadowosc jest duzym ulatwieniem przy tworzeniu kolejnego wdrozenia w oparciu o stary modul.

  4. Wojciech Soczyński pisze:

    Ja też uważam, że to świetna rzecz, dlatego warto by ludzie poznali tą technikę :)

  5. Global Dope Here this offshoot

  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.