Your SlideShare is downloading. ×
PHP Используем Dependency Injection и Container
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

PHP Используем Dependency Injection и Container

1,094

Published on

Dependency Injection - базовые понятия, и использование DI в Symfony 2.Выступление на Минской встрече PHP разработчиков.

Dependency Injection - базовые понятия, и использование DI в Symfony 2.Выступление на Минской встрече PHP разработчиков.

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

No Downloads
Views
Total Views
1,094
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. План PHP Используем Dependency Injection и Container • Что такое Dependency Injection (DI)? • Что такое Контейнер служб (контейнер внедрения зависимости)? • Как пришли к понятию Dependency Injection? • Использование DI и Контейнера в Symfony 2.
  • 2. Обо мне Александр Неманов https://www.facebook.com/alexander.nemanov bug@tut.by Skype: gftrades.support
  • 3. DI - что это? Внедрение зависимости (англ. Dependency injection) — процесс предоставления внешней зависимости программному компоненту. Является специфичной формой “Обращения контроля” (Inversion of control, IoC) IoS - это важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в коде программы. • Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракции. • Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. Корнями иерархий должны быть абстрактные классы, в то время как конкретные классы в этой роли выступать не должны. Абстрактные базовые классы должны беспокоиться об определении функциональности, но не о ее реализации. Контейнер служб - это реализация принципа внедрения зависимости bug@tut.by skype: gftrades.support
  • 4. Покодируем. И это работает… class Invoice { public function createUserInvoice($user) { $order = new PayedOrder('paypal'); $orderId = $order->createOrder(); $pfdGenerator = new PDFGenerator(); $invoice = $pfdGenerator->generate($orderId); $mailer = new Mailer('sendmail'); $mailer->send($user, $invoice); } } $invoice = new Invoice(); $invoice->createUserInvoice('Alex'); bug@tut.by skype: gftrades.support
  • 5. SOLID (S) Single responsibility principle - Принцип единственности ответственности (O) The Open Closed Principle - Принцип открытости/закрытости (L) The Liskov Substitution Principle - Принцип замещения Лисков (I) Interface segregation - Принцип разделения интерфейса (D) Dependency inversion - Принцип инверсии зависимости bug@tut.by skype: gftrades.support
  • 6. Строки которые сведут с ума class Invoice { public function createUserInvoice($user) { $order = new PayedOrder('paypal'); $orderId = $order->createOrder(); $pfdGenerator = new PDFGenerator(); $invoice = $pfdGenerator->generate($orderId); $mailer = new Mailer('sendmail'); $mailer->send($user, $invoice); } } bug@tut.by skype: gftrades.support
  • 7. Для теста немного “подшаманим” (принцип открытости/закрытости) class Invoice { public function createUserInvoice($user) { $order = new PayedOrder('paypal'); $orderId = $order->createOrder(); $pfdGenerator = new PDFGenerator(); $invoice = $pfdGenerator->generate($orderId); // TODO: Не забудь на проде раскоменьтить, а то будет как всегда!!! /* $mailer = new Mailer('sendmail'); $mailer->send($user, $invoice); */ } } bug@tut.by skype: gftrades.support
  • 8. Рефакторим на пути к DI class Invoice { private $order, $generator, $mailer; public function __construct(PayedOrder $order, PDFGenerator $generator, Mailer $mailer) { $this->order = $order; $this->generator = $generator; $this->mailer = $mailer; } public function createUserInvoice($user) { $orderId = $this->order->createOrder(); $invoice = $this->generator->generate($orderId); $this->mailer->send($user, $invoice); } } $order = new PayedOrder('paypal'); $pfdGenerator = new PDFGenerator(); $mailer = new Mailer('sendmail'); $invoice = new Invoice($order, $pfdGenerator, $mailer); $invoice->createUserInvoice('Alex'); bug@tut.by skype: gftrades.support
  • 9. Что мы еще можем сделать? class Invoice { private $order, $generator, $mailer; public function __construct(PayedOrder $order, PDFGenerator $generator, Mailer $mailer) { $this->order = $order; $this->generator = $generator; $this->mailer = $mailer; } public function createUserInvoice($user) { $orderId = $this->order->createOrder(); $invoice = $this->generator->generate($orderId); $this->mailer->send($user, $invoice); } } $order = new PayedOrder('paypal'); $pfdGenerator = new PDFGenerator(); $mailer = new Mailer('sendmail'); $invoice = new Invoice($order, $pfdGenerator, $mailer); $invoice->createUserInvoice('Alex'); bug@tut.by skype: gftrades.support
  • 10. Используем Dependency Injection Container (DIC) (Рискнем!) Используем Dependency Injection Container (DIC) (Рискнем!) bug@tut.by skype: gftrades.support
  • 11. Реализуем свой, простой DIC bug@tut.by skype: gftrades.support class Container { protected $s=array(); function __set($k, $c) { $this->s[$k] = $c; } function __get($k) { return $this->s[$k]($this); } }
  • 12. Используем $c = new Container(); $c->payment_system = function ($c) { return 'paypal'; }; $c->order = function ($c) { return new PayedOrder($c->payment_system); }; $c->pfdGenerator = function ($c) { return new PDFGenerator(); }; $c->mailer_transport = function ($c) { return 'sendmail'; }; $c->mailer = function ($c) { return new Mialer($c->mailer_transport); }; $c->invoice = function ($c) { return new Invoice($c->order, $c->pfdGenerator, $c->mailer); }; $invoice = $c->invoice; $invoice->createUserInvoice('Alex'); bug@tut.by skype: gftrades.support
  • 13. Symfony DI Контейнер служб (или же контейнер внедрения зависимости) - это также PHP объект, который управляет созданием служб (т.е. объектов). bug@tut.by skype: gftrades.support
  • 14. Symfony DIC composer.json { "require": { "symfony/dependency-injection": "v2.3.0", "symfony/yaml": "v2.3.0", "symfony/config": "v2.3.0", } } bug@tut.by skype: gftrades.support
  • 15. Symfony DIC services.yml parameters: payment.type: paypal mailer.transport: sendmail services: order: class: PayedOrder arguments: [%payment.type%] generator_pdf: class: PDFGenerator mailer: class: Mailer arguments: [%mailer.transport%] invoice: class: Invoice arguments: [@order, @generator_pdf, @mailer] bug@tut.by skype: gftrades.support
  • 16. Symfony DIC // index.php use SymfonyComponentDependencyInjectionContainerBuilder; use SymfonyComponentConfigFileLocator; use SymfonyComponentDependencyInjectionLoaderYamlFileLoader; $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); $loader->load('services.yml'); $invoice = $container->get('invoice'); $invoice->createUserInvoice('Alex'); bug@tut.by skype: gftrades.support
  • 17. Symfony DI • Параметры службы • Массивы параметров • Импорт конфигурации • Использование одних служб внутри других • Опциональные зависимости • constructor injection, setter injection, property injection • Опциональные ссылки на службы • Основные службы Symfony и службы от сторонних разработчиков (session, templating, mailer, request) • Разные конфиги для разных окружений (prod, dev, test) bug@tut.by skype: gftrades.support
  • 18. SF DI - продвинутая конфигурация • Публичные и приватные службы • Псевдонимы (alias) • Таги (tags) templating.helper, twig.extension... bug@tut.by skype: gftrades.support
  • 19. Фреймворки использующие DIC Реализация внедрения зависимостей PHP5 • DiContainer • Garden • Xyster Framework • Lion Framework • TYPO3 Flow • Symfony 2 Dependency Injection • Zend Framework 2 • Laravel's IoC Container bug@tut.by skype: gftrades.support
  • 20. To be, or not to be: that is the question Используйте мудро, но bug@tut.by skype: gftrades.support
  • 21. DI это требование, если вы используете TDD Сильная связанность затрудняет тестирование Работа с внешними ресурсами затрудняет тестирование Пример внешних ресурсов: • Обращение к сторонним сервисам • Файловая система • Файлы конфигурации • … bug@tut.by skype: gftrades.support
  • 22. Почему мы используем DI • Late Binding - сервисы могут быть заменены другими сервисами • Extensibility - код может быть легко расширен и повторно использован • Parallel development - разработка кода с низкой связанностью упрощает командную параллельную разработку • Maintainability - классы с четкими границами легко сопровождать • Testability - модули могут быть протестированы bug@tut.by skype: gftrades.support
  • 23. Вопросы bug@tut.by skype: gftrades.support

×