Чуть сложнее чем Singleton: аннотации, IOC, АОП

1,870 views

Published on

Some thoughts about IoC, annotations and AOP in PHP & ZF for ZFConf Ukraine 2010.
Language: Russian.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,870
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
7
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Чуть сложнее чем Singleton: аннотации, IOC, АОП

  1. 1. Чуть сложнее чем Singleton Аннотации, IoC, АОПKirill chEbba Chebunin
  2. 2. О докладе• Аннотации, IoC, АОП• АОП через IoC + аннотации• Далеко не новые технологии• В PHP мало используются
  3. 3. 1. Аннотации
  4. 4. Аннотации@Entitypublic class User {/**/}[Class]public class User {/**/}/** @Entity */class User {/**/}
  5. 5. Аннотации• Метаданные, описывающие классы, методы, свойства• Компромисс между «соглашениями» и «конфигурацией»• Конфигурация непосредственно в коде
  6. 6. Аннотации. Аннотации в PHPPHPUnit – возможно, одна из первыхбилиотек с использованием аннотаций./** * @expectedException RuntimeException */public function testException(){}
  7. 7. Аннотации. Аннотации в PHPZend_Reflection – чтение PHPDoc тегов.$class = new Zend_Reflection_Class( MyClass);$docBlock = $class->getDocblock();$tag = $docBlock->getTag(myTag);echo $tag->getDescription();
  8. 8. Аннотации. Аннотации в PHPИ, конечно, Doctrine 2/** @Entity */class MyPersistentClass{ /** @Column(type="integer") */ private $id; /** @Column(length=50) */ private $name; // type defaults to string //...}
  9. 9. Аннотации. Аннотации в PHP$reader = new AnnotationReader();$reader->setDefaultAnnotationNamespace( DoctrineORMMapping‘);$entity = $reader->getClassAnnotation( MyPersistentClass, DoctrineORMMappingEntity);if ($entity !== null) { //Entity! Do smth}
  10. 10. Аннотации. Аннотации в ZFМожно использовать в ActionHelper’ах.•ContextSwitch (AjaxContext)•Cache
  11. 11. Аннотации. Аннотации в ZF/** @ContextSwitchable */class FooController extends Zend_Controller_Action{ /** @Context({"xml", "json"}) */ public function barAction() { // Do smth }}
  12. 12. Аннотации. Аннотации в ZF/** @PageCache(tags={"foo", "bar"}) */public function barAction(){ // Do smth}
  13. 13. 2. IoC
  14. 14. IoC. ЗависимостиЧто же такое зависимости?class FooController extends Zend_Controller_Action{ public function barAction() { $service = new MyUserService(); $service->getUser(1); }}
  15. 15. IoC. КонтейнерШаг 1. Берем готовый объект из хранилища.•Service Locator•Registry•etc
  16. 16. IoC. Контейнер// Zend_Registry$service = Zend_Registry::get(userService);// Bootstrap container$service = $this->getInvokeArg(bootstrap) ->getResource(userService);
  17. 17. IoC. Интерфейсы наше всеШаг 2. Используем интерфейсы.interface UserService{/**/}class MyUserService implements UserService{/**/}
  18. 18. IoC. Интерфейсы наше всеinterface UserService{ public function getUser($id);}
  19. 19. IoC. Интерфейсы наше всеclass MyUserService implements UserService{ protected $userDao; public function __construct(UserDao $userDao) { $this->userDao = $userDao; } public function getUser($id) { $this->userDao->getUserById($id); }}
  20. 20. IoC. Dependency Injection• Класс прдоставляет метод/свойство для инъекции (внедрения) зависимости.• Внедрением занимается вышестоящий компонент
  21. 21. IoC. Dependency Injectionprotected $userService;public function setUserService( UserService $userService){ $this->userService = $userService;}public function barAction(){ $this->userService->getUser(1);}
  22. 22. IoC. Dependency Injection•Кто же будет заниматься внедрением?•Как просто конфигурировать зависимости?
  23. 23. IoC. Symfony DI• Специальные IoC контерйнеры.• Для PHP Symfony Dependency Injection• Есть версия для 5.+• Есть версия для 5.3
  24. 24. IoC. Symfony DI• Контейнер содержит описание объектов.• ZF2 - LazyLoadingBroker
  25. 25. IoC. Symfony DI<service id="userDao" class="NotMyUserDao"> <!-- Some DB params for example --></service><service id="userService" class="MyUserService"> <argument type="service" id="userDao"/></service>
  26. 26. IoC. Symfony DI$container = new ContainerBuilder();$loader = new XmlFileLoader($container);$loader->load(path/container.xml);/* @var $service UserService */$service = $container->get(userService);
  27. 27. IoC. ZF + Symfony DIМожно подменить контейнер.$application->getBootstrap() ->setContainer($container);$application->bootstrap()->run();
  28. 28. IoC. ZF + Symfony DIА можно запустить непосредственноФронтКонтроллер.$front = $container->get(frontController);$front->dispatch();
  29. 29. IoC. ZF + Symfony DI. ПроблемыОбъекты, создаваемые ZF автоматически•Контроллеры•ActionHelper’ы•ViewHerlper’ы•Плагины
  30. 30. IoC. ZF + Symfony DI. РешенияZF 1.x•ActionHelper для инъекции в контроллеры•Реализация Dispatcher’а•Наследование Zend_Controller_Action•Наследование Zend_View
  31. 31. IoC. ZF + Symfony DI. РешенияZF 2.x•ActionHelper для инъекции в контроллеры•Реализация PluginLoader’a•Dispatcher через PluginLoader
  32. 32. 3. АОП
  33. 33. АОП. Что это?• Прадигма программирования• Сквозная функциональностьЛог, обработка ошибок, права доступа, транзакции.• Первая реализация - AspectJ
  34. 34. АОП. Основные понятия• JoinPoint (Точка соединения) – метод, которому нужно добавить функциональность• Pointcut (Срез) – набор JoinPoint’ов
  35. 35. АОП. Реализация на PHP/** @Cached */public function cacheMeDude() {/* */}/** @Log */public function plzLogMe() {/* */}/** @Transactional */public function iNeedTransaction() {/* */}
  36. 36. АОП. Что это?• Aspect (Аспект)• Advice (Совет) Before, After, AfterException, AfterReturn, Around
  37. 37. АОП. Что это?Advice как метод класса./** @Around("@annotation(Cached)") */public function cache( ProceedingJoinPoint $joinPoint){ // Cache result or return from cache}
  38. 38. АОП. Реализация на PHPИзменить работу метода, не трогая готовыйкод.•Переопределение в рантайме (runkit, etc)•«Предкомпилирование» кода•Прокси классы
  39. 39. АОП. Реализация на PHPПодмена объекта, прокси объектом.Например, при создании в IoC контейнере.$objectProxy = ProxyClass::createProxyFromObject( $object, $handler );
  40. 40. АОП. Реализация на PHPГенерируем прокси-классы с помощьюZend_CodeGeneratorclass TestAOPCheProxy extends TestAOP{ // Override all methods}
  41. 41. АОП. Реализация на PHPOverride всех public и protected методовpublic function method($foo, $bar){ return $this->invocationHandler->invoke( $this, new ReflectionMethod( get_parent_class(__CLASS__), __FUNCTION__ ), func_get_args() );}
  42. 42. АОП. Реализация на PHP/** @Cached */public function cacheMeDude() {/* */}/** @Log */public function plzLogMe() {/* */}/** @Transactional */public function iNeedTransaction() {/* */}
  43. 43. АОП. Реализация на PHP$aopedObject->cacheMeDude();•ProxyClass::cacheMeDude(); – Handler::invoke() • CacheAspect::cache() – ? OriginalClass::cacheMeDude()
  44. 44. АОП. Заключение• Не панацея• Может усложнить систему• Тестирование
  45. 45. The EndСпасибо за внимание.Kirill chEbba ChebuninEmail: iam@chebba.orgTwitter: iamchEbba

×