最佳实践Symfony2(工厂)服务

时间:2015-05-16 09:13:53

标签: php web-services symfony

昨天我在IRC Symfony2频道讨论了最佳实践方法和教程(sf2-website上的书籍,食谱)。

  1. 有人说服务一直是无国籍的。他的意思是在服务类中不应该与实体连接。但是,如果我需要预先格式化数据库中的内容,我应该如何使用用户生成的内容?

  2. 虽然有人说服务应该是无状态的,但我根据本教程创建了服务和工厂服务: http://brentertainment.com/2012/02/28/contextualizing-your-symfony2-application-with-the-service-container/

  3. 我的配置服务的命名目前有点糟糕,但我目前没有策略或良好的命名概念。

    目前我在Controller中调用$this->get('test.conf')->getCategory('data-browser')。它感觉很好"通过这种方式做到这一点,因为我不必在控制器中重复该功能。 然后,服务 test.conf 调用工厂服务 test.conf_factory ,它将获得service.configuration的实例。

    问题:

    • 服务是否适合像我这样获得预先格式化的内容?

    • 服务配置是否正确?或者我可以以任何方式简化test.conf_factorytest.conftest.configuration吗? 目前我真的不知道我是否做得对。

    • 使用服务test.configuration并创建另一个服务,它只是在构造函数中创建一个test.configuration实例并通过调用方法&返回它会更好(或是否可能) #39;让'实例? (http://symfony.com/doc/current/components/dependency_injection/introduction.html) 是否有像大多数symfony开发人员那样的证明方式?

    配置工厂:

    namespace Test\CoreBundle\Factory;
    
    use Test\CoreBundle\Entity\Account;
    use Test\CoreBundle\Service\Configuration;
    
    
    class ConfigurationFactory
    {
        private $user;
        private $configuration;
    
    public function __construct(Account $user = null, Configuration $configuration)
        {
            $this->user = $user;
            dump($user);
            $this->configuration = $configuration;
        }
    
        public function get()
        {
            if ($this->user) {
             //   dump($this->user);
                $this->configuration->setAccountid($this->user->getId());
            }
            return $this->configuration;
        }
    }
    

    配置服务:

    <?php
    namespace test\CoreBundle\Service;
    
    class Configuration {
    
        private $em;
    
        private $category;
    
        private $accountid;
    
        /**
         * Values from database
         * @var array
         */
        private $ValuesFromDB = null;
    
        public function __construct($em)
        {
            $this->em = $em->getRepository('TestCoreBundle:Conf');
        }
    
        public function setAccountid($accountid) {
            $this->accountid = $accountid;
            $this->loadAll();
        }
        public function loadAll() {
             $DBconf = $this->em->findAllByAccount($this->accountid);
    
             foreach($DBconf as $key => $conf) {
                 $values[$conf->getCategory()][$conf->getKey()] = $conf->getValue();
            }
    
             $this->ValuesFromDB = $values;
    
        }
    
        public function setCategory($category) {
            $this->category = $category;
        }
    
        public function getCategory($category) {
            return $this->ValuesFromDB[$category];
        }
    
        public function get($key) {
            return $this->ValuesFromDB[$this->category][$key];
        }
    
    }
    
    services:
        test.account_factory:
            class: test\CoreBundle\Factory\AccountFactory
            arguments: [@security.context]
        test.account:
            class: test\CoreBundle\Entity\Account
            factory_service: test.account_factory
            factory_method: get
    
    
        test.configuration:
            class: test\CoreBundle\Service\Configuration
            arguments: [@doctrine.orm.entity_manager]          
    
        test.conf_factory:
            class: test\CoreBundle\Factory\ConfigurationFactory
            arguments: 
                - @test.account
                - @test.configuration
    
        test.conf:
            class: Configuration
            factory_service: test.conf_factory
            factory_method: get
    

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解您的设计问题,但我想您实际上要做的是根据特定实体(此处为您的用户)从数据库中检索一些数据。 我会尝试分享你的意见:

我从你的设计中看到的是你误解了工厂的概念:在这里,它显然毫无用处。

  • 首先,你试图在这里设计的不是工厂。它似乎更像是你试图使用依赖注入原则而没有真正掌握它。
  • 其次,我认为当您必须实施此类设计并实施此类工具时,您必须考虑您实际上真正尝试做什么,以及您的工具应该< / strong>做。根据您的问题我可以理解,您似乎想要检索与您的用户相关的一些与您的实体无关的特定数据。我要问的第一个问题是:为什么您的数据没有链接到用户的业务逻辑?

然后,我会尝试通过思考来修改你的工具:我的工具应该做什么?难道你不认为你实施的设计过于复杂吗?

如果我明白你想做什么,我想你可以使用你的工具:

  • 首先,手动检索帐户。无需注入任何帐户或为每个帐户创建配置的实例。我想,对于更高级别的代码,您可以先检索您的帐户。
  • 其次,使用服务(是的,服务,因为服务不再是一个简单的类,其中包含额外的DI等等),它可以检索您需要的数据。

您在帖子开头的问题实际上并不是要求提出,因为您不应该在课程中注入帐户的实例。最后,像:

// I get my account 
$myAccount = $this->getEntityManager()->getRepository('TestCoreBundle:Conf')->find(/* ... */);
$configurationManager = $this->get('configuration_manager');
// The manager permits me to get the "extra stuff" related to this account.
$confStuff = $configurationManager->getConfigurationStuffFromAccount($myAccount);

......如果我理解的话,应该是解决问题的方式。

那样:

  • 您的服务 configuration_manager 不依赖于任何存储库或任何帐户。
  • 您可以有效地使用服务和DI。