简体   繁体   English

Symfony2中的策略模式

[英]Strategy pattern in Symfony2

I'm trying to build simple service for rendering various types of pages. 我正在尝试构建用于呈现各种类型页面的简单服务。 Basic concept is having something like: 基本概念是这样的:

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

...which would be designed as Strategy pattern . ......将被设计为战略模式 Page types would implement interface with render method and page.service would call it. 页面类型将实现与render方法的接口, page.service将调用它。 The problem is I'd like to use Doctrine in page type classes. 问题是我想在页面类型类中使用Doctrine。 What are my options here? 我有什么选择? I'd like to avoid creating service for each of these classes. 我想避免为每个类创建服务。 Is that even possible? 这甚至可能吗? Is it possible to make them container aware without being services? 是否有可能在没有服务的情况下使容器更容易识别? Possibly, in the future, some page type might need something more than only Doctrine, so I need to keep in mind also that. 可能在将来,某些页面类型可能需要的不仅仅是Doctrine,所以我还要记住这一点。

Services are exactly what you want here. 服务正是您想要的。 Being able to inject the dependencies for the particular strategy in question. 能够为所讨论的特定策略注入依赖关系。 Then injecting the particular strategy into the controller (could also be a dynamic renderer that chooses the strategy at runtime). 然后将特定策略注入控制器(也可以是在运行时选择策略的动态渲染器)。

ContainerAware is a really bad practice, it couples the object in question to all of the services in the container. ContainerAware是一个非常糟糕的做法,它将有问题的对象耦合到容器中的所有服务。 Thus, I'd strongly recommend avoiding it. 因此,我强烈建议避免它。

I'm assuming PageType is an example of a strategy class. 我假设PageType是策略类的一个例子。 In that case, you could inject the dependencies by the page.service and you wouldn't need to define the strategies as services. 在这种情况下,您可以通过page.service注入依赖page.service ,而不需要将策略定义为服务。

Each strategy probably depends on different objects and therefore I guess you could make them ContainerAware . 每个策略可能取决于不同的对象,因此我猜你可以使它们成为ContainerAware Here's an example how to do it 这是一个如何做到的例子

// 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.
}

So basically each strategy would extend ContainerAware and the page.service would inject the container. 所以基本上每个策略都会扩展ContainerAware ,而page.service会注入容器。


EDIT 编辑

If all of your strategies are dependant on the same services, I'd inject them instead of the whole container. 如果你的所有策略都依赖于相同的服务,我会注入它们而不是整个容器。

class MyPageService {

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

        // do stuff
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM