Шаблон стратегии в Symfony2 - PullRequest
7 голосов
/ 13 января 2012

Я пытаюсь создать простой сервис для рендеринга различных типов страниц. Основная концепция имеет что-то вроде:

$somePageType = new PageType(...);
$this->get('page.service')->render($somePagetype);

... который будет иметь вид шаблон стратегии . Типы страниц реализуют интерфейс с методом render, а page.service вызывает его. Проблема в том, что я хотел бы использовать Doctrine в классах типов страниц. Какие у меня есть варианты? Я хотел бы избежать создания сервиса для каждого из этих классов. Это вообще возможно? Возможно ли сделать их осведомленными о контейнерах, не будучи сервисами? Возможно, в будущем для некоторых типов страниц может потребоваться нечто большее, чем просто Doctrine, поэтому я должен помнить и об этом.

Ответы [ 2 ]

3 голосов
/ 14 октября 2013

Услуги именно то, что вы хотите здесь. Возможность вводить зависимости для конкретной стратегии. Затем добавление конкретной стратегии в контроллер (также может быть динамическим средством визуализации, которое выбирает стратегию во время выполнения).

ContainerAware - очень плохая практика, он связывает рассматриваемый объект с всеми службами в контейнере. Поэтому я настоятельно рекомендую избегать этого.

1 голос
/ 14 января 2012

Я предполагаю, PageType является примером класса стратегии.В этом случае вы можете внедрить зависимости с помощью page.service, и вам не нужно будет определять стратегии как сервисы.

Каждая стратегия, вероятно, зависит от разных объектов, и поэтому, я думаю, вы могли бы сделать их ContainerAware.Вот пример, как это сделать

// This is the page.service class
class MyPageService {

    public function render(PageTypeInterface $page_type) {
        $page_type->setContainer($this->container);

        // do stuff
    }
}

// This is the type strategy
class MyStrategyType extends ContainerAware implements PageTypeInterface {
    // you can access the container after MyPageService has injected it.
}

Таким образом, каждая стратегия будет расширяться ContainerAware, а page.service будет вводить контейнер.


РЕДАКТИРОВАТЬ

Если все ваши стратегии зависят от одних и тех же сервисов, я бы внедрил их вместо всего контейнера.

class MyPageService {

    public function render(PageTypeInterface $page_type) {
        $page_type->setService($this->container->get('my_service'));

        // do stuff
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...