Когато за пръв път се сблъсках със Zend Framework бях заслепен от високото ниво на абстракция, изчистения код и богатата библиотека. Тогава бях на 18 години, а познанията ми по ООП бяха ограничени до разработване на семпли сайтове, използващи 2-3 класа + Smarty. На теория знаех всичко за ООП, но концептуално нямах идея как да се възползвам от силата на тази технология, просто бях чувал, че да използваш класове и обекти е готино. Zend Framework изигра главна роля в професионалното ми развитие, и успя да пречупи мирогледа ми, превръщайки тогаващата представа за програмирането в нещо много по-различно. Zend Framework ме научи да мисля обектно.

Илюзията на всеки програмист, който знае ООП на теория(но не познава design pattern-и например), е че той няма нужда от приети в общността похвати, той е велик и няма защо да се учи от някой. Това срещам във почти всеки PHP програмист в днешно време. Преди да се сблъскам със ZF, аз също бях един твърдоглав начинаещ.

Нека опиша един проект, който не използва фреймуърк: разполага с един клас, който често се казва Main или Core, а в него се съдържат методи от връзка с база данни до извличане на информация за продукти, та чак до потребителска регистрация. Това е корабът Майка. Често се случва корабът Майка да достигне над 10 000 реда код, което е голяма гордост за автора. Някои програмисти си мерят… редовете код, но в сорс кода количество != качество.

Преминаването от този стар стил към обектно-ориентирано мислене е много труден (това че ползваш два-три класа не значи, че проекта ти е обектно-ориентиран, а по-скоро обектно-дезориентиран).

Когато преди година разбрах, че се готви нова версия на любимата ми платформата, бях повече от сигурен, че ще има куп нови неща за учене и имах чувството, че Zend ще промени света на PHP за втори път.

Какво не беше наред със Zend Framework 1?

Въпреки, че храня доста сантиментални чувства към ZF, не мога да пренебрегна факта, че има много неща, които не ми харесват.

Тромава модулна система

Модулната система в Zend Framework беше добавена по-късно. В по-ранните версии на ZF не беше обърнато внимание на модулите и затова възможността за модули в ZF 1 e по-скоро нагодена. Липсват много важни възможности като модулна конфигурация и конфигуриран лоудър за класове. Всички тези неща бяха не чак толкова трудно поправими, но създадоха нерви.

Прекалено много Сингълтон

Един от най-често срещаните шаблони в платформата е Singleton. Но защо Сингълтон е лош? Той е толкова лесен за импелентация и използване. Истината е, че времето на сингълтоните мина и ние трябва плавно да забравим за тях.

Защо Сингълтон е лош?

Да вземем например Zend_Controller_Front – гръбнака на MVC имплементацията в Zend. Този клас предоставя единствен обект в цялото приложение чрез метода getInstance(). Извиква се лесно от всички крайща на кода. Благодарение на това ние можем да получим информация за текущата http заявка както и много други ценни параметри, които той съхранява. Но какво правим, ако искаме да сменим Zend_Controller_Front с наша собствена имплементация на класа? Това е напълно невъзможно, защото останалите класове в библиотеката Zend_Controller използват този сингълтон и няма чист начин да променим това. Те винаги ще ползват този клас. Не можем да редактираме останалите класове в пакета, защото трябва да правим това всеки път когато излезе нова версия на Zend Framework 1.*.

Освен сингълтоните, лоши са всички други класове, предоставящи статични методи с важна имплементация, като например Zend_Controller_Action_HelperBroker –  той също се извиква статично от много места и не можем да го сменим с наш клас.

Някои ограничения на Zend_Db

Един от най-любимите ми компоненти в Zend e Zend_Db.

Zend_Db е добре измислен абстрактен слой, чиято цел е да облече SQL заявките в обектно-ориентирани дрехи. В структурата на компонента са използвани шаблони от Patterns of Enterprise Application Architecture като Table Data Gateway и Row Data Gateway. Използването на Zend_Db е истинско удоволствие. За един проект със средна сложност, Zend_Db може да осигури функционалност без да има нужда да се пише нито една SQL заявка.

Какво не е наред със Zend_Db?

Много е трудно да се критикува толкова мощен инструмент, но съм се сблъсквал с някои малки ограничения на компонента.

Класът Zend_Db_Adapter осигурява 4-те стандартни CRUD метода insert(), update(), delete() и select(), с чиято помощ може лесно да боравите със съответните SQL команди, но това което ограничава функциалността на този клас е, че не можете лесно да обогатите функциалността на някой от тези методи.

Да вземем например insert(). С този метод се създава заявка INSERT INTO .. VALUES .., но ако искам да добавя ключовата дума IGNORE (която ще репресира грешки предизвикани от дублаж на редове с уникални ключове) ще ударя на камък, защото такава настройка в Zend_Db не съществува. В случея лошото е, не че няма INSERT IGNORE заявки, а че не мога лесно да променя Zend_Db, така че да добавя тази функционалност.

Същата ситуация е и с INSERT .. ON DUPLICATE KEY UPDATE.

Ново начало за Zend Framework

Една от главните цели на първата версия на ZF беше да стандартизира употребата на PHP като се лансират новите възможности на 5-та версия. Минаха години от първия релийз на фреймуърка и PHP също се промени. Много от възможностите, планувани за дългоочакваната версия 6 бяха пуснати предварително във феноменалната 5.3.

Наистина езикът се изкачи на още по-високо ниво, приличайки на големия брат Java. Запознахме се с namespace-ове, callback функции, и още други интересни възможности се появиха в следващата версия – PHP 5.4.

С напредването на времето в общността се усети нуждата от примерна и стабилна имплементация на всички тези възможности и следваща мажорна версия на ZF беше неизбежна. Дълго се дискутираха идеи относно бъдещето на новия фреймуърк, но като че ли цялата енергия беше концентрирана около Dependency Injection.

Темата не засяга обучение върху основите на Zend Framework 2, а по-скоро пропаганда. Затова няма да видите конкретни примери за употреба и т.н.

Dependency Injection

Да, Zend Framework 2 трябваше да бъде Dependency Injection базиран. Но защо? Какво ще ни даде това така далечно и неясно понятие?

Всъщност приобщаването на DI в PHP общността беше една сериозна крачка напред.

Повече за DI тук

Гъвкавата архитектура

Най-важната екстра, която дава новата архитектура на ZF 2, е че с използването на Dependency Injection можем да сменим всеки клас в библиотеката с наша собствена имплементация. Лансирано е използването на интерфейси, а за сингълтони не става и дума.

Мощна конфигурация

Подмяната на класове става посредством специални настройки в така наречената DI конфигурация. Няма да давам конкретни примери, защото целта на статията е да обобщя на кратко възможностите на Zend Framework 2.

Имплементация на Service Locator

[TBS_ALERT]   Само за разбирачи[/TBS_ALERT]

Комбинацията между Dependency Injection и Service Locator е като да правиш любов с много красива и нежна жена. Ако приемем, че Dependency Injection е силна, но груба страст, то Service Locator добавя нежност и красота.

Когато зависимостите в системата ни са много и всички те се инжектират посредством DI контейнер, то има много случеи, когато обекти ще бъдат инжектирани напразно, което би се отразило на производителността.

Service Locator-ите решават този проблем като предоставят инстанциите само когато има нужда от тях. Въпреки, че това е напълно различен патърн, той може да бъде използван много хармонично заедно с DI (което е широка практика). Резултатът е инжектиране не на конкретни инстанции, а на самия Service Locator, чрез който се осъществява достъп до нужните услуги/инстанции.

Въпреки, че DI е в сърцето на Zend Framework 2, разработчиците си нямат взимане-даване директно с DI конфигурацията на контейнера. Самият DI слой е скрит под библиотека, наречена Zend\ServiceManager, която всъщност представлява мощна имплентация на Service Locator. Тя разполага със собствена конфигурация, която от своя страна говори със Zend\Di.

Новата модулна система

ДА! Това е нещо, от което наистина имахме нужда! Но какво точно ни дава тази нова модулна система?

Преносимост

Преносимостта е нещо, към което всеки програмист се стреми. Целта на новата модулна система е да концентрира разпределянето на логиката в модули, така че да се улесни пренасянето и адаптирането на тази логика в други приложения.

За разлика от Zend Framework 1, не е задължително модулите в ZF 2 да са MVC. Може да напишете модул, който предоставя библиотека, осигуряваща логика за други модули. Например може да имаме модул PayPal, в който да се съдържат класове за разплащане с PayPal, но не и съответни контролери, view скриптове и модели.

Като най-ярък практически пример за мощността на новата модулна система е създадената общност за разпространение на модули – http://modules.zendframework.com. На тази страница всеки може да публикува модули и всеки може да използва такива. Това ще направи разработването на проекти със ZF 2 още по-бързо и лесно.

Лесна конфигурация

В Zend Framework 1 бяхме свикнали да пишем платформената конфигурация в .ini файлове. Това осигуряваше добра четимост, но в някои случеи беше трън в очите за хората, които търсеха висока производителност. Освен това липсваше зареждане на модулна конфигурация по подразбиране.

В ZF 2 за конфигурация по подразбиране се използва асоциативен масив.

Освен глобална конфигурация, всеки модул може да предостави своя собствена конфигурация. При стартиране на системата, настройките на всички налични модули се смесват заедно с глобалната конфигурация, и се зареждат в модул-мениджърът.

Заключение

Няма да ми стигнат 100 страници да опиша (дори на кратко) всички нововъведения в ZF 2, но наблегнах на най-важните и забележителни възможности на новата платформа. Разбира се, въпреки положителните отзиви около ZF 2 аз не смятам, че той е перфектен. Все още е рано и не съм се натъкнал на неприятни характеристики, но съм сигурен, че съществуват.

С голямо удоволствие ще наблюдавам израстването и развитието на фреймуърка, но съветвам ZF разработчиците да не прибързат със Zend Framework 2.

Zend Framework не е най-добрият фреймуърк, той просто е в класация „Топ 1“.