Symfony2/Doctrine, having to put business logic in my controller? And duplicating controller?

后端 未结 2 771
别那么骄傲
别那么骄傲 2020-12-31 01:37

I have a somewhat complex pricing mechanism in my application- Here are some of my business rules to set the stage (Entities are bolded):

  • A
2条回答
  •  Happy的楠姐
    2020-12-31 02:05

    You simplified your example so I don't really know all the details but here's my attemt to solve your problem.

    Note that you might actually need more then one service but you should get the idea based on my example.

    Basically follow the principle - One class has one responsobility.

    Price calculator calculates the Price:

    namespace MyNamespace;
    
    class PriceCalculator
    {
        private $entityManager = null;
    
        public function __construct(Doctrine\ORM\EntityManager $entityManager)
        {
            $this->entityManager = $entityManager;
        }
    
        /**
         * @return PriceInterface
         */
        public function calculate()
        {
            // do your stuff and return Price
        }
    }
    

    Price is described by the PriceInterface:

    namespace MyNamespace;
    
    interface PriceInterface
    {
        public function getUnitPrice();
    
        public function getTotalPrice();
    
        public function getOptionsPrice();
    }
    

    Price calculator service has a dependency on the entity manager:

    my_namespace.price_calculator:
      class:     MyNamespace\PriceCalculator
      arguments: [ @doctrine.orm.default_entity_manager ]
    

    Controller uses price calculator service to get the price:

    public function indexAction() 
    {
        $priceCalculator = $this->get('my_namespace.price_calculator');
        $price = $priceCalculator->calculate();
    
        $unitPrice = $price->getUnitPrice();
        $totalPrice = $price->getTotalPrice();
        $optionsPrice = $price->getOptionsPrice();
    }
    

    If you need a Request or other service you can inject them using DIC or manually as a parameter to calculate() method.

    Note that I injected EntityManager to the PriceCalculator service but you might define data providers as services and inject them instead (for really complicated things).

    You could also push all queries to repositories and pass entities to your PriceCalculator.

提交回复
热议问题