【问题标题】:Strategy pattern in Symfony2Symfony2 中的策略模式
【发布时间】:2012-01-13 17:13:16
【问题描述】:

我正在尝试构建简单的服务来呈现各种类型的页面。基本概念是这样的:

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

...将被设计为Strategy pattern。页面类型将使用render 方法实现接口,page.service 将调用它。问题是我想在页面类型类中使用 Doctrine。我在这里有什么选择?我想避免为每个类创建服务。这甚至可能吗?是否有可能在不作为服务的情况下让它们感知容器?可能在未来,某些页面类型可能需要的不仅仅是 Doctrine,所以我也需要记住这一点。

【问题讨论】:

    标签: php design-patterns symfony


    【解决方案1】:

    服务正是您想要的。能够为所讨论的特定策略注入依赖项。然后将特定策略注入控制器(也可以是在运行时选择策略的动态渲染器)。

    ContainerAware 是一种非常糟糕的做法,它将相关对象与容器中的所有服务耦合在一起。因此,我强烈建议避免使用它。

    【讨论】:

      【解决方案2】:

      我假设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.
      }
      

      所以基本上每个策略都会扩展ContainerAwarepage.service 会注入容器。


      编辑

      如果您的所有策略都依赖于相同的服务,我会注入它们而不是整个容器。

      class MyPageService {
      
          public function render(PageTypeInterface $page_type) {
              $page_type->setService($this->container->get('my_service'));
      
              // do stuff
          }
      }
      

      【讨论】:

      • 传递容器是不好的。如果他的对象需要教义,他应该通过在教义对象的构造函数中添加一个参数来要求它。
      • @meze 当然可以,但是如果每个策略都有不同的依赖关系呢?这将是唯一的方法。但是,我个人会将所有策略都定义为服务。
      • 您将如何测试您的策略?在没有 symfony 的情况下在另一个项目中重用?
      • @meze 有效点。如果我让我的策略容器知道,那么测试和重用确实很困难。这就是为什么我说我会让它们成为所有服务,这意味着通过构造函数或设置器传递依赖关系。那时测试和代码重用都不是问题。
      • 问题是,我不知道在其他策略中是否需要不同的服务。这当然是可能的,我想为此做好准备。因此,将每个策略声明为服务可能是最好的方法。使用服务只会给这样简单的事情增加更多(不必要的)工作,这让我很恼火。但我想我在这里没有太多选择。
      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多