Deweloperzy pracujący nad rozwojem frameworka postawili duży nacisk na to by produkt, był bardziej spójny, dobrze udokumentowany, zwiększający produktywność i szybkość uruchamiania aplikacji. Zmiany oznaczają przełom.
Do pełnego zrozumienia rangi wprowadzanych modyfikacji, potrzebna jest podstawowa znajomość pierwszej wersji Zend Framework, wzorców projektowych i PHP 5.3. Prześledźmy je zatem wraz z wprowadzonymi zmianami.
Prosty i szybki proces nauki
Pierwszy krok jest najtrudniejszy. To stwierdzenie, dokładnie oddaje najczęściej napotykany problem, przez rozpoczynających przygodę z pierwszą wersją frameworka, programistów. Pomimo dobrej dokumentacji i dopracowania rozdziału „Quick Start”, programista napotyka na dodatkowe problemy związane z rozwojem aplikacji jak:
- Spójność. Dokumentacja opisuje jak korzystać z poszczególnych komponentów takich jak Zend_Cache, Zend_Translate, Zend_Form, itd. ale brakuje kompletnego przykładu, pokazującego jak połączyć istniejące komponenty, w bardziej złożonej i dynamicznie rozszerzanej o nowe funkcjonalności aplikacji.
- Niekonsekwencja API. Pierwsza wersja frameworka zawiera heplery, pluginy i filtry, niektóre z nich posiadają spójny interfejs a pozostałe już nie. Cześć z nich posiada niejawne metody tworzone poprzez __call(), które trudniej jest znaleźć w kodzie. Część z komponentów pozwala na konfigurację poprzez przekazanie array lub obiektu Zend_Config natomiast pozostałe wyłącznie array. Niektóre komponenty pozwalają na konfigurację camelCaseOption natomiast inne na underscore_separated.
Rozwiązanie, które deweloperzy zaproponowali jako remedium na powyższe problemy można przedstawić w kilku zwięzłych punktach:
- Stworzenie podręcznika demonstrującego kompletny cykl tworzenia aplikacji internetowej w ZF2.
- Udokumentowanie i przedstawienie wszystkich przypadku użycia dla każdego z komponentów
- Ujednolicenie interfejsów w całym obszarze frameworka, które nie tylko ułatwi proces nauki ale także zwiększy produktywność programisty poprzez eliminację dezorientacji wynikającej z niekonsekwencji w API.
- Standaryzacja mechanizmu konfiguracji – stworzenie nowego komponentu, który będzie odpowiedzialny przekazywanie i walidację danych.
- Przygotowanie sandbox ZF2, który umożliwia błyskawiczny start z frameworkiem.
Prostota w rozszerzaniu
Główną zaletą Zend Framework jest jego możliwość rozszerzania, przez dewelopera, o nowe komponenty czy funkcjonalności. Jednak mimo tego że w pierwszej wersji framework’a jest to relatywnie proste to istnieje kilka kluczowych przypadków, dla których taka możliwość jest bardzo utrudniona:
- Wykorzystanie Singleton’ów w wielu miejscach w aplikacji, bardzo komplikuje lub wręcz uniemożliwia rozszerzenie lub podmianę funkcjonalności. Przykładami takich komponentów to Zend_Controller_Front, Zend_Auth, Zend_Session.
- Częste użycie klas abstrakcyjnych zamiast interfejsów, powoduje rozszerzanie lub podmianę komponentów znacznie trudniejszym. Część z klas abstrakcyjnych jest już bardzo bogata w elementy, które w nowej funkcjonalności nie potrzebujemy, w konsekwencji podmieniony kod posiada dużą ilością zbędnych metod.
- Twarde zależności uniemożliwiają w wielu miejscach rozdzielenie funkcjonalności lub jej podmianę na nową. Najlepszym przykładem jest Zend_View, który jest nierozłącznym składnikiem wielu komponentów np.: Zend_Controllerze_Action, Zend_Form przez co próba skorzystania z Smarty lub OPT zamiast standardowego systemu szablonów jest bardzo utrudniona.
- Brak możliwości rozszerzenia elementów, z których użytkownik mógłby wynieść wiele korzyści. Idealnym przykładem jest Zend_Db, który gdyby oferował możliwość rozszerzania o plugin’y mógłby zaoszczędzić pracy przy tworzeniu struktur drzewiastych, cachowania itp. a dodatkowo kod byłby wielokrotnego użytku.
Podstawowy plan działań jaki został obrany przez deweloperów by rozwiązać powyższe problemy, można streścić w kilku punktach:
- Identyfikacja kluczowych interfejsów dla komponentów i typowanie/rzutowanie do nich zamiast do klas abstrakcyjnych.
- Usunięcie singletonów gdzie tylko jest to możliwe, natomiast jeżeli nie jest to możliwe przenieść zachowanie do obiektów współpracujących (collaborating objects)
- Usunięcie twardych zależności na rzecz DI
- Określenie komponentów, które powinny pozwalać na rozszerzalność i współpracę z innymi obiektami.
Poprawiona wydajność
Szybkość działania pierwszej wersji frameworka, zachwycała tylko na początku (do wydania 1.5) a z każdą jego kolejną odsłoną szybkość stopniowo spadała. Developerzy, podejmując pracę nad drugą wersją frameworka, określili sobie za cel poprawę wydajności rzędu 200-300%.
Jako że jest już dostępne do testowania developerskie wydanie ZF2 to można stwierdzić iż separacja zależności i wykorzystanie na szeroką skalę dependency injection oraz lazy load przynosi spodziewane korzyści, ale to nie wszystko. Całkowicie został przebudowana modułowość i MVC. Teraz moduł jest elementem niezależnym od MVC. Moduł może korzystać z MVC i definiować własny bootstrap, routing i konfigurację. W dużych i różnorodnych projektach takie podejście do problemu może mieć ogromny wpływ na poprawę wydajności gdyż moduł będzie ładował tylko to co jest konieczne dla jego prawidłowego działania.
Kolejnym etapem w poprawie wydajności jest pomoc programiście w zdobyciu informacji o dobrych praktykach optymalizacyjnych. Developerzy chcą to osiągnąć poprzez stworzenie odpowiedniego działu w dokumentacji.
Rozwój i utrzymanie
Rosnąca popularność ZF niesie za sobą ogromną ilość zmian i nowych komponentów. Na chwilę obecną projekt składa się z 2 milionów linii kodu w tym 14 tysięcy linii testów jednostkowych. Nad jego rozwojem i spójnością czuwają trzy osoby z zespołu Zend’a i ogromna ilość programistów z całego świata zaangażowana w jego rozwój i tworząca nowe komponenty.
Projekt o takiej skali wymaga odpowiedniego podejścia do rozwoju i utrzymania. Jednym z rozwiązań mającym pomóc w tym zadaniu jest przejście z centralizowanego systemu kontroli wersji na rozproszony system kontroli wersji – GIT – jest on znany developerom, zapewnia możliwość weryfikacji i identyfikowania programistów współpracujących nad kodem, umożliwi łatwe łatanie i łączenie zmian dzięki czemu jest bardziej skutecznym narzędziem w prowadzeniu i utrzymywaniu projektu.
Kolejnym aspektem rozwoju jest integracja z projektami firm trzecich. Do tej pory taka integracja była nie lada wyzwaniem (wprowadzenie Zend_Application uprościło ten proces). Teraz developerzy zamierzają jasno i klarowne określić w jaki sposób biblioteki powinny być integrowane z ZF2 co zapewni dostęp do bardziej wszechstronnych rozwiązań dla użytkownika bez nakładu dodatkowej pracy.
Wzór wykorzystania PHP 5.3
PHP 5.3 wnosi do języka wiele nowości: przestrzenie nazw, funkcje anonimowe, late static binding, goto itd. dlatego jak najbardziej zrozumiałym jest podejście developerów do wykorzystania tego potencjału.
Można wyróżnić następujące etapy, które zostaną uwzględnione podczas re-factoringu kodu źródłowego frameworka:
- Migracja na przestrzenie nazw w celu zniwelowania kolizji w nazewnictwie z bibliotekami firm trzecich jak i kodu prywatnego użytkownika.
- Usunięcie wszystkich wywołań create_funciton() i zastąpienie go funkcjami anonimowymi.
- Identyfikacja kodu, który może skorzystać z nowości w PHP 5.3
Podsumowanie
Pierwsze szkice planu rozwoju drugiej odsłony frameworka jasno wskazywały że będziemy mieli do czynienia z ewolucją ukierunkowaną na wykorzystanie nowych możliwości PHP 5.3, aktualizację dokumentacji, poprawienie wydajności. Jednak z czasem obraz ten nabiera coraz to większej ostrości. Mimo, że na razie mamy do czynienia jeszcze z wydaniem alpha, to projekt w implementacji jest na tyle rewolucyjny w porównaniu do poprzedniej wersji frameworka, że przez moment zastanawiałem się, czy nie warty by zmienić jego nazwy. Osobiście podoba mi się kierunek rozwoju i z niecierpliwością czekam na pierwszą betę, która ma zostać wydana pomiędzy 17-20 października podczas trwania ZendCon 2011.
Gabriel Habryn
Słownik:
- ZF – Zend Frameork
- DI – Dependency Injection
- MVC – Model View Controller
Linki:
Gabriel Habryn – Programista PHP w Empathy Internet Software House. Absolwent Zarządzania i Inżynierii Produkcji na Akademii Górniczo-Hutniczej w Krakowie. Wcześniej związany z firmą Promotor i Agencją Reklamową Propaganda. Prywatnie fan wykładów buddyjskiego guru OSHO, książek Paoliniego i cięższego brzmienia.