Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

49
Контейнер Сервисов Что? Где? Когда? Ханов Руслан [email protected]

Upload: mailru-group

Post on 20-Jan-2017

4.737 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Контейнер Сервисов

Что? Где? Когда?

Ханов Руслан[email protected]

Page 2: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Полезные ссылки● https://yugeon-dev.blogspot.ru/2010/07/inversion-of-control-containers-and_21.html

● https://symfony.com/doc/current/book/service_container.html

● https://habrahabr.ru/post/278049/

2

Page 3: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

SOLID

Первые пять принципов OOAD

Объектно-ориентированный анализ и проектирование

3

Page 4: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Dependency inversion principle

Принцип инверсии зависимостей

4

Page 5: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Реализация

● Фабричный метод (Factory method)

● Локатор сервисов (Service locator)

● Внедрение зависимости (Dependency injection)

5

Page 6: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Фабричный метод

6

Page 7: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

7

# Factory.php

class Factory{ public function getRepository() { return new Repository(); }}

# Controller.php

class Controller{ public function executeAction() { $factory = new Factory(); $repository = $factory->getRepository(); # do some action ... }}

Page 8: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Локатор сервисов

8

Page 9: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

9

# ServiceLocator.php

class ServiceLocator{ public function get($name) { return $this->services[$name]; }}

# Controller.php

class Controller{ public function executeAction() { $repository = $this->serviceLocator->get(‘repository’); # do some action ... }}

Page 10: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Внедрение зависимости

10

Page 11: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

11

# Controller.php

class Controller{ # dependency injection … public function executeAction() { $repository = $this->repository; # do some action ... }}

Page 12: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Реализация (для закрепления)

● Фабричный метод (Factory method)

● Локатор сервисов (Service locator)

● Внедрение зависимостей (Dependency injection)

12

Page 13: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Плюсы

13

Page 14: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Плюсы

● Гибкость

14

Page 15: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Плюсы

● Гибкость● Тестируемость

15

Page 16: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Плюсы

● Гибкость● Тестируемость● Немногословность (no boilerplate code)

16

Page 17: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Минусы

17

Page 18: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Минусы

● “Размазанная” логика

18

Page 19: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Минусы

● “Размазанная” логика● Использование общего состояния (Doctrine index)

19

Page 20: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Минусы

● “Размазанная” логика● Использование общего состояния (Doctrine index)

● Переусложнение

20

Page 21: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Реализация в symfony

Внедрение зависимостей

21

Page 22: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Реализация в symfony

Внедрение зависимостей

Контейнер сервисов (Service container)

22

Page 23: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Контейнер сервисов

● Сервисы● Контейнер

23

Page 24: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Типы внедрения

24

● Через конструктор● Через вызов метода● Через свойство

24

Page 25: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Через конструктор

25

Page 26: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

26

# Controller.php

class Controller{ public function __construct(Repository $repository) { $this->repository = $repository; }

public function executeAction() { $repository = $this->repository; # do some action ... }}

# services.yml

services: repository: class: Repository controller: class: Controller arguments: - “@repository”

Page 27: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Через вызов метода

27

Page 28: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

28

# Controller.php

class Controller{ public function setRepository(Repository $repository) { $this->repository = $repository; }

public function executeAction() { $repository = $this->repository; # do some action ... }}

# services.yml

services: repository: class: Repository controller: class: Controller calls: - [setRepository, [“@repository”]]

Page 29: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Через свойство

29

Page 30: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

30

# Controller.php

class Controller{ /** * @var Repository */ public $repository;

public function executeAction() { $repository = $this->repository; # do some action ... }}

# services.yml

services: repository: class: Repository controller: class: Controller properties: repository: “@repository”

Page 31: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Типы внедрения (для закрепления)

● Через конструктор● Через вызов метода● Через свойство

31

Page 32: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Примеры внедрения

● Controller

● Repository

● Form & FormType

● Command

● Lots of services!

32

Page 33: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

33

# Controller.php

class Controller{ public function executeAction() { # do some action ... }}

# services.yml

services: controller: class: Controller

Page 34: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

34

# Repository.php

class Repository{ public function find($id) { # find entity ... }}

# services.yml

services: repository: class: Repository factory: - “@doctrine.orm.default_entity_manager” - getRepository

Page 35: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

35

# FormType.php

class FormType{ public function buildForm(FormBuilderInterface $builder, array $options) { # build form ... }}

# services.yml

services: form_type: class: FormType tags: - {name: form.type, alias: form_type} form: class: Symfony\Component\Form\Form factory: - “@form.factory” - create arguments: - form_type

Page 36: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

36

# Command.php

class Command{ protected function execute(InputInterface $input, OutputInterface $output) { # execute command ... }}

# services.yml

services: repository: class: Command tags: - {name: console.command}

Page 37: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

37

# lots-of-services.yml

services: validator: class: Validator serializer: class: Serializer client: class: Client storage: class: Storage translator: class: Translator

Page 38: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Антипаттерны

● Использование service locator (вне инфраструктурного

кода)

● Использование micro service locator

● Семантическая конфигурация

38

Page 39: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Service locator

39

Page 40: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

40

# Controller.php

class Controller{ public function setContainer(ContainerInterface $container) { $this->container = $container; }

public function executeAction() { $repository = $this->container->get(‘repository’); # do some action ... }}

# services.yml

services: repository: class: Repository controller: class: Controller calls: - [setContainer, [“@service_container”]]

Page 41: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Micro service locator

41

Page 42: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

42

# Controller.php

class Controller{ public function setFormFactory(FormFactory $formFactory) { $this->formFactory = $formFactory; } public function executePostAction() { $formPost = $this->formFactory->create(‘form_type_post’); # do post action ... } public function executePutAction() { $formPut = $this->formFactory->create(‘form_type_put’); # do put action ... }}

# services.yml

services: controller: class: Controller calls: - [setFormFactory, [“@form.factory”]]

Page 43: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Семантическая конфигурация

43

Page 44: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

44

# CompilerPass.php

class CompilerPass extends CompilerPassInterface{ public function process(ContainerBuilder $containerBuilder) { $definition = $container->getDefinition(‘service’);

$definition->setLazy(true); }}

# services.yml

services: service: class: Service # lazy: true

Page 45: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

# CompilerPass.php

class CompilerPass extends CompilerPassInterface{ public function process(ContainerBuilder $containerBuilder) { $parameters = $container->getParameter(‘vendor’);

foreach ($parameters as $key => $value) { $container->setParameter(‘vendor_’ . $key, $value);

} }}

# services.yml

parameters: vendor: key_1: value_1 key_2: value_2services: service: class: Service arguments: - “%vendor_key_1%” - “%vendor_key_2%”

45

Page 46: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Антипаттерны (для закрепления)

● Использование service locator (вне инфраструктурного

кода)

● Использование micro service locator

● Семантическая конфигурация

46

Page 47: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Плюсы (для закрепления)

● Гибкость● Тестируемость● Немногословность (no boilerplate code)

47

Page 48: Руслан Ханов, «Контейнер сервисов — Что? Где? Когда?»

Заключение

● Многое становится проще● Есть несколько реализаций● Если не читать документацию, можно “заиграться”

● Можно самостоятельно реализовать

48