Posty oznaczone etykietą ioc

Symfony 2: pierwsze wrażenia

Nowości w Symfony 2

  • PHP 5.3 jako standard i korzystanie z przestrzeni nazw
  • Zupełnie nowy kod, zdecydowane odchudzenie klas, czuć lekkość
  • Dependency Injection (IoC)
  • Events
  • Modułowa architektura, nie tylko pod postacią katalogów o nazwie modules/plugin
  • Rezygnacja z pluginów jako mikroaplikacji na rzecz Bundles
  • Źródła hostowane na GitHub

Bundle 1: Marketing

Prezentacje, konferencje, świetny design stron przemawiają za rewolucyjnością nowego produktu SensioLabs.

Faktycznie, w świecie PHP może być to jakaś rewolucja, ale chyba głównie za sprawą samego PHP 5.3 i namespaces zaciągniętych z "szóstki". A źrodła Symfony? Ano jak to PHP - trochę Javy trochę C, np. klasy Request/Response w których zaimplementowano tylko akcesory (powstają obiekty o niezmiennym stanie). W Django najważniejsze middleware opierają się na możliwości modyfikacji obiektu Request dodając np. właściwość user. Proste i dziala. W Symfony 2 to nie przejdzie, ubijany jest dynamizm języka programowania.

Bundle 2: Dependency Injection

Kiedyś bardzo potrzebowałem takiego mechanizmu. Otóż za pomocą konfiguracji (PHP/Yaml/XML/etc) można zdefiniować skonfigurowane usługi pod unikalnymi nazwami. Konfiguracja może odbywać się przez wstrzyknięcie argumentów do konstruktora lub wybranych metod (argumentami mogą być wartości lub odwołania do innych zdefiniowanych usług).

W teorii można swobodnie wymieniać/parametryzować poszczególne instancje klas. W praktyce stosuje się to rzadko lub wcale.

Popełniłem kiedyś taki plugin do Symfony 1.x - sfIocPlugin - wzorowałem się na IoC ze Springa. ''' Dependency Injection w Symfony może przydać się przy większych projektach, gdzie pewne usługi mogą być wymienialne w zależności od wdrożenia. Osobiście jednak uważam, że realizacja "większych projektów" w PHP to utopia. Może komuś się to jednak przyda.

EDIT: Dependency Injection sprawdza się w unit testach (o ile środowisko unit testów umożliwia użycie DI), szczegóknie w połączeniu z mock-objects.

Bundle 3: Events

System zdarzeń w Symfony 2 jest prosty. Jest dość dobrą realizacją wzorca obserwatora. Autor przyznaje, że wzorował się na notyfikacjach z Cococa.

Implementacja ta przypomina mi naszego firmowego EventBrokera napisanego chyba w 2006 roku. Osobiście wolę django.signals z racji rejestrowania obserwatora do konkretnej instancji sygnału. Z kolei w Symfony obserwator (listener) rejestrowany jest w instancji dispatchera podając nazwę sygnału.

Nasuwają się dwie wady (z doświadczenia):

  • dispatcher może nie mieć zarejestrowanego zdarzenia (trzeba znaleźć odpowiedni dispatcher, przez który będzie przebiegał event),
  • rejestracja i notyfikacje odbywają się przez nazwę - robiąc literówkę przy connect nie mamy szans na informacje o błędzie; takie błędy znajduje się zwykle po kilku godzinach.

Bundle 4: Super wydajność

Wydajność została zwiększona, ale nie uważam że o te mityczne 2.5x.

Benchmark strony "Congratulations..." (index.php) z sandboxa, dla ab -c 100 -n 1000:

  • Symfony 2: 32.18 [#/sec]
  • Symfony 1.2: 19.58 [#/sec]

To jest nieco powyżej 1.5x. Żeby jednak trochę podrasować wersję 1.2 wyłączyłem w settings.yml użycie bazy danych (test Symfony 2 też nie używał BD).

Widok o podobnej złożoności w Django serwowany jest nawet do 200 rq/sec. Strona główna portalu opartym na Django (z użyciem memcache) jest serwowana w trybie developerskim w porywach do 160 req/sec.

Wydajność Symfony 2 nie zachwyca.

Bundle 5: Formularze

Czytałem tylko kod. Są to niemal te same nieudolne formularze, o których już pisałem - Symfony forms vs Django forms.

Podsumowanie

Szkoda czasu.