symfony2中的每个类都需要是一个服务吗?

时间:2016-05-12 01:18:17

标签: symfony oop design-patterns

简介移到了最底层:

现在我正在开发一个管理订单和产品的小型系统。 我正在尝试从控制器重构代码块到业务和服务类,这就是我想要提取的内容

/src/domain/bundle/Business/
/src/domain/bundle/Services/

所以在商业中,我会有一个Order类,它会做一些计算,其中一些计算需要数据库中的数据(动态)。

这正是我遇到的问题:

  1. 控制器加载需要处理的订单数组
  2. 控制器将需要处理的订单发送到OrderBusiness
  3. OrderBusiness类需要从数据库中获取产品价格
  4. 现在我被困了.. 我正在尝试做的是,我创建了一个ProductsService类,它从数据库中返回所需的产品和价格,但是如何在不定义OrderBusiness类的情况下从我的OrderBusiness类调用此类。 1}} class作为服务并使用ProductsService

    注入它

    说明:

    如果我的问题似乎有点普遍而且无知,我很安静。 我已经使用Symfony2不到一年了,有些事情我无法解读,即使在阅读了文档后,还有很多问题。

3 个答案:

答案 0 :(得分:4)

你可以做任何你想做的事情,但通常更好地坚持使用Symfony的默认方式:

  1. Controller从请求中获取数据,验证数据,调用其他类并呈现请求(通常使用Twig或JsonResponse::create)。

  2. 要从数据库获取数据,有存储库。当它们返回普通的旧PHP对象(PO​​PO)时,它会很好。通常使用Doctrine magic进行管理。

  3. 要处理对象(聚合,过滤,连接到外部服务等),您可以创建服务。您不能使用Service(任何类名称正常)将其后缀并放入Service文件夹。

  4. 当你创建许多简单的课程后,遵循"单一责任原则"将它们与依赖注入连接起来很方便。那么你的课程就不会过多地相互依赖,而且在不改变所有文件中的代码的情况下,将一个课程与另一个课程交换起来很容易,也适合进行测试。

答案 1 :(得分:1)

Symfony:依赖注入

所以,Symfony没有要求将所有类定义为服务!服务层 - DependencyInjection

  1. 您必须在容器中注册新服务,以便在其他系统/服务/业务逻辑中访问此服务。此性能:将仅创建一次服务(new SomeService),并将此对象缓存在内部缓存层中。
  2. 如果您想每次都创建一个新的服务实例,可以将scope: prototype添加到service definition
  3. 这个系统在服务之间的许多引用方面都有所不同。
  4. 你的问题/解决方案:

    在最佳实践中 - 绝不!

    作为解决方案:您可以使用singlton,或使用静态服务。

    但是,我建议使用依赖注入模式层来解决这个问题,并为每个逻辑创建所有类。原因:

    1. 单一责任
    2. 使用PHPSpec / PHPUnit轻松测试(因为每个类 - 一个业务逻辑)。
    3. 您可以在__constructor中注入不带参数$this->dependencyService = new SomeService()
    4. 的常用逻辑
    5. 如果您不想在容器中定义服务,但另一个服务有引用,您可以将依赖服务定义为private public: false
    6. 任何条件(请求,用户,范围等)的动态服务(通过工厂创建)
    7. 就我而言:

      作为我的另一个项目(Orders,Products,Variants ......)的例子

      我有:

      1. ProductRepository - 适用于加载产品,变体。
      2. PriceCalculator - 用于计算产品价格(我从产品属性加载价格,但您可以为其他存储空间中的加载价格注入PriceLoader服务)。
      3. OrderProcessor - 处理订单。
      4. 控制器:

        class OrderProcessingController
        {
            private $productRepository;
            private $orderProcessor;
        
            public function __construct($productRepository, $orderProcessor)
            {
                $this->productRepository = $productRepository;
                $this->orderProcessor = $orderProcessor;
            }
        
            public function processForProduct($product)
            {
                $product = $this->productRepository->find($productId = $product);
        
                if (!$product) {
                    // Control for product not found
                }
        
                $this->orderProcessor->processForProduct($product);
        
                return new Response('some html');
            }
        }
        

        在此我们只加载产品,如果没有找到控件并调用进程。改进简单易用的测试。

        订单处理器:

        class OrderProcessor
        {
            private $priceCalculator;
            private $priceLoader;
        
            public function __construct($priceCalculator, $priceLoader)
            {
                $this->priceCalculator = $priceCalculator;
                $this->priceLoader = $priceLoader;
            }
        
            public function processForProduct($product)
            {
                $price = $this->priceLoader->loadForProduct($product);
                $price = $this->priceCalculator->calculateForProduct($price, $product);
        
                // Some processing
        
                return $order;
            }
        }
        

        在这个课程中 - 我们为产品加载价格,计算,创建订单并在必要时调用另一个处理。改进简单易用的测试。

        P.S。

          

        现在我正在开发一个管理订单和产品的小型系统。

        可以使用任何微框架吗? Silex作为示例或Symfony Microframework,并完全取消订阅依赖注入层?

答案 2 :(得分:0)

  

现在我被困了..我试图做的是,我做了一个ProductsService   class,从数据库中返回所需的产品和价格,

使用存储库类进行业务查询。不要混合应用层。您还可以将存储库定义为服务。

当class表示通用接口或表示算法(例如business)时,将其定义为服务。