DI and Zend Framework (ZFConf2011)

3,448 views
3,360 views

Published on

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,448
On SlideShare
0
From Embeds
0
Number of Embeds
725
Actions
Shares
0
Downloads
27
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

DI and Zend Framework (ZFConf2011)

  1. 1. Гибкая архитектура Zend Framework приложений сиспользованием Dependency Injection
  2. 2. Алексей КачаевSenior/Lead PHP Developer atCogniance4+ года опыта c PHP3+ года использования ZendFrameworkАктивный участникzendframework.ru/forumZF2 contributor
  3. 3. Мои контактыEmail:kachayev@gmail.comTwitter:@kachayevFacebook:http://www.facebook.com/kachayevGithub:https://github.com/kachayev
  4. 4. Мои контактыEmail:kachayev@gmail.comTwitter:@kachayevFacebook:http://www.facebook.com/kachayevGithub:https://github.com/kachayev
  5. 5. О чем мы будем говорить1. Что такое зависимости2. IoC в теории и на практике3. Реализация DI в Zend Framework с использованиемSymfony DI Container4. Антипаттерны, или что мешает управлятьзависимостями5. IoC в Zend Framework 2.0
  6. 6. Что такое зависимости (dependency)
  7. 7. Что такое зависимости: начало
  8. 8. Что такое зависимости: далее
  9. 9. Что такое зависимости: и...Задача на разминку: как тестируя ProfileControllerзаменить DbConnection на фейковый?
  10. 10. Что здесь плохого?1. Жесткость и хрупкость (изменения => поломка)архитектуры (по Роберту Мартину)2. "Нетестируемость" системы3. Отсутствие прозрачности связей (сложность)4. Код не самого нижнего уровня иерархии практическиневозможно реиспользовать (монолитность)
  11. 11. IoC patterns:теория и практика
  12. 12. IoC в теории1. Принцип Inversion of Control:Модули верхних уровней не должны зависить от модулейнижних уровней.Легко сказать!2. Реализация на практике:Ответственности за зависимости переходят к классамверхнего уровня.
  13. 13. IoC на практикеУ Фаулера:http://martinfowler.com/articles/injection.htmlДва основных паттерна:1. Service Locator2. Dependency Injection (Внедрение или ИнъекцияЗависимостей)http://ru.wikipedia.org/wiki/Dependency_Injection(разница в том, на кого перекладывается ответственностьза управление зависимостями)
  14. 14. Service LocatorСуть: зависимостями управляет специальный объектServiceLocator
  15. 15. Service LocatorДалее используем везде, где есть зависимости
  16. 16. Dependency Injection Суть: зависимый объект заранее передается через setter или конструктор.Зависимости Сборка
  17. 17. 3 шага к Dependency InjectionШаг 1. Getter/SetterШаг 2. Интерфейс (interface)Шаг 3. Контейнер
  18. 18. 3 шага к Dependency Injection
  19. 19. На один уровень выше
  20. 20. Идем дальше: игра в пятнашки"Двигаем" все зависимости "наверх" в единый Контейнер:
  21. 21. Используем контейнерКонтролер создаем не прямо, а через берем изконтейнера:Чего еще хотелось бы:- build контейнера из конфигурационного файла- shared-объекты контейнера, для возможности следитьза уникальностью объекта в рамках контейнера (принеобходимости)
  22. 22. Что дает DI?1. Любой класс в иерархии зависимостей можно отдельнопротестировать2. Код легко перенести в другое окружение и/илиприложение3. Один шаг в сторону принципа единой ответственностикласса
  23. 23. Сравнение двух подходов спрактической точки зренияService Locator+ очень просто внедрить даже в существующий (дажекрупный проект) - точечность изменений+ легко заложить дефолтные процедуры полученияобъекта- сложно переопределять объектыDI+ более управляемый при сильном разрастании+ обеспечивает большую прозрачности иерархий- практически не поддерживает точечного внедренияВозможно использование смешаного подхода
  24. 24. ZF 1.* &Symfony DI Container
  25. 25. PHP DI контейнеры1. Symfony Dependency Injection2. Pico Container3. Yadif_Container4. Phemto5. .... (много других)
  26. 26. Возможности Symfony DI1. Удобное представление контейнера черезконфигурацию (xml, yaml)2. Гибкие возможности конфигуратора3. Dump собранного контейнера в php-код для увеличенияпроизводительности4. Shared-объекты контейнера5. Хранение параметров
  27. 27. Пример блоков конфигурации
  28. 28. Пример блоков конфигурации
  29. 29. DI в ZendВарианты:- контейнер для Application- контейнер как ресурс- контейнер как часть Bootstrap
  30. 30. Как мы поступим?Прим. Очень много зависимостей, на которые мы пока несмотрим (helpers, plugins, View, request/response и т.д.)1. Контейнер будет внедрен в Bootstrap вместостандартного Zend_Registry2. В контролере, контейнер можно будет получить черезспециальный Helper - ServiceContainerЭто идеологически Service Locator.3. PreDispatch-обработка инъекций (ServiceContainerhelper)Sourceshttps://github.com/kachayev/zfconf-speech
  31. 31. Service locator helper
  32. 32. Service locator helper - использованиеПлюсы+ простота имплементации+ легкость "точечного" внедренияМинусы- "частичный" DI - контроллер не являетсясамодостаточным и связан с helper-ом
  33. 33. Dependency Injection придиспечирезации1. В helper-e добавляем функцию preDispatch() - будетвызвана FrontController-ом перед диспечеризациейконтроллера2. Получаем в ней объект контроллера3. Через Zend_Reflection_Class анализируем свойста иметоды, на предмет наличия @Inject аннотации4. Инъектируем зависимости (через setter или черезрефлекцию)
  34. 34. Dependency Injection придиспечирезацииПлюсы + те жеМинусы- контроллер не является самодостаточным и связан сциклом диспечирезации
  35. 35. DI - обратить вниманиеНегативный момент DI - "привязанность" к inject-ированию. Во избежании проблем лучше пользоватьсяException-ами вроде:Безопаснее - RuntimeException()
  36. 36. DI - lazy loadingИногда бывают ситуации, когда нам нужно получитьнекий объект с "тяжелыми" объектами в иерархиизависимостей.UserService->AuthProvider->AuthAdapter->DbConnectionНо DbConnection может не пригодится. Решение -фабрика.
  37. 37. DI - unit-тестирование1. Любой объект может быть собран на любом уровнеиерархии зависимостей, а значит может бытьпротестирован отдельно.2. Сборка тестируемых объектов может проводится какконтейнером (используем тестовый конфиг), так и в"ручном" режиме (используя принцип DI-ready вархитектуре каждого объекта).
  38. 38. Антипаттерны IoC:что мешает управлять зависимостями
  39. 39. АнтипаттерныНе-injectable:1. Singleton- заменяется на shared-объект в рамках контейнера2. Static class- отпадает необходимость, так как есть возможностьинъектировать объект3. Cross-reference- объкты ссылаются друг на друга. напримерBootstrap->FrontController->Bootstrap
  40. 40. АнтипаттерныНе-логичные:4. "Блуждающий контейнер"- зависимости собираются в контейнер, но сам койнейнерпередается (injected) вниз по иерархии
  41. 41. IoC & ZF2
  42. 42. IoC в Zend Framework2007 годZend_Di component proposal (Federico Cargnelutti)http://framework.zend.com/wiki/display/ZFPROP/Zend_Di+-+Federico+CargneluttiНепринято из-за комплексности2008 годZend_Container component proposal (Bradley Holt)http://framework.zend.com/wiki/display/ZFPROP/Zend_Container+-+Bradley+Holt
  43. 43. IoC в Zend Framework 2.0Matthew Weier OPhinney"Zend Framework 2 Patterns"Roadmap...- ...- Inversion of Control1. Service Locator2. Dependency Injector(в официальном ZF 2.0 Roadmap их нет)
  44. 44. IoC в Zend Framework 2.010 Марта, 2011Proposal for ServiceLocator and DependencyInjector(http://framework.zend.com/wiki/display/ZFDEV2/Proposal+for+ServiceLocator+and+DependencyInjector)Пример использования новых компонентовhttps://github.com/weierophinney/zf-examples/tree/projects%2Fzf2.di/zf2-diВызвало достаточно бурное обсуждение в рассылкеконтрибьюторов.Замечание: лицензия ZF не позволяет использоватьсуществующие решения.
  45. 45. IoC в Zend Framework 2.0Приведенные в Proposal примеры достаточноискусственны и тривиальны.Типа такого:
  46. 46. IoC в Zend Framework 2.0Что не дает возможности оценить необходимость ивыигрыш от смешивания подходов в некий DI basedService Locator (похоже на java-ский Avalon Framework):
  47. 47. Спасибо за внимание! Вопросы ???
  48. 48. Мои контактыEmail:kachayev@gmail.comTwitter:@kachayevFacebook:http://www.facebook.com/kachayevGithub:https://github.com/kachayev

×