2012-01-13 6 views
7

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

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

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

ответ

1

Я предполагаю, что 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 введет контейнер.


EDIT

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

class MyPageService { 

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

     // do stuff 
    } 
} 
+0

Нехорошо проходить мимо контейнера. Если его объект требует доктрины, он должен потребовать его, добавив параметр в конструктор для объекта doctrine. – meze

+0

@meze конечно, но что, если каждая стратегия имеет разные зависимости. Это был бы единственный способ. Тем не менее, я бы лично определил все стратегии как услуги на самом деле. – gilden

+0

и как бы вы проверили свои стратегии? повторное использование в другом проекте без symfony? – meze

3

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

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

Смежные вопросы