2011-11-05 5 views
18

मैं यहाँ मंच तैयार करने के लिए अपने व्यवसाय के नियमों के कुछ (संस्थाओं बोल्ड कर रहे हैं) कर रहे हैं मेरे आवेदन के में कुछ हद तक एक जटिल मूल्य निर्धारण तंत्र है:सिम्फनी 2/सिद्धांत, मेरे नियंत्रक में व्यावसायिक तर्क डालना है? और डुप्लिकेटिंग नियंत्रक?

  • एक उत्पाद के लिए अद्वितीय मूल्य अंक हो सकता है एक दिया गया ग्राहक, वेबसाइट, या ग्राहक समूह
  • एक उत्पाद कभी कभी एक या अधिक अतिरिक्त विकल्प अपने स्वयं के मूल्य अंकयामूल्य नियम हो सकता है हो सकता है।
  • उत्पाद में उपयोगकर्ता द्वारा चुने गए अद्वितीय जोड़, जो अनिवार्य रूप से एक मूल्य और एक पूर्णांक है।

अभी, मैं मूल्य अंक के लिए एक EntityRepository अनिवार्य रूप से आधार उत्पाद के लिए सही कीमत बिंदु निर्धारित करने के लिए किया है। अद्वितीय जोड़ और विकल्प के लिए भी यही है।

PricePointRepository

public function getThePrice($Product, $qty, $Website, $Customer = null) 
{ 
    //all logic to get product price for this given instance goes here. Good. 
} 

नियंत्रक (सरलीकृत)

public function indexAction() 
{ 
    $Product = $em->dostuffwithpostdata; 
    $qty = POST['qty']; //inb4insecure trolls 
    $Website = $em->dostuff(); 
    $Customer = (if user is logged in, return their object with $em, otherwise null as it is a guest or public person); // No business logic here, just understanding the request. 

    $price = $em->getRepository(PricePointRepository)->getThePrice($Product,$qty,Website,$Customer); 

    $Options[] = $em->dostuffwithPOSTdata; 
    $optionsPrice = 0; 
    //Below is some logic directly related to pricing the product. 
    foreach($Options as $option) { 
     if($option->hasRule()) { 
      $optionsPrice += $ruleprice; //after some other stuff of course) 
     } else { 
      $optionsPrice += $em->getRepository(OptionPricePoints)->getPrice($option->getID(),$qty); 
     } 
    } 

    $uniqueAdditionPrice = $em->stuff; 

    $finalprice = $price + $optionsPrice + $uniqueAdditionPrice; //This is logic related to how I price this type of product! 
    $unitprice = $finalprice/$qty; 

    //twig stuff to render and show $finalprice, $unitprice, $uniqueAdditionPrice 
} 

सिर्फ उत्पाद पृष्ठ के लिए है यही कारण है कि। जब मैं कार्ट में जाता हूं, ऑर्डर सहेजता हूं, आदि, तब होता है जब यह तर्क पुन: उपयोग करने की आवश्यकता है। जैसा कि आप देख सकते हैं, मैं भंडार वर्गों में अपने व्यापार तर्क के आधार पर डेटा खींचने के लिए संपूर्ण रूप से सिद्धांत का उपयोग करता हूं।

मैं खुशी से urdoingitwrong उत्तरों का स्वागत करता हूं, क्योंकि मुझे सच में लगता है कि यह गलत है। मैं इसे ठीक करने के बारे में कैसे जा सकता हूं? कुछ सुंदर एक सेवा है जो अनिवार्य रूप से इस प्रकार है होगा:

$pricer = getPricerService->Pricer($Entities,$postdata,$etc); 
$unitPrice = $pricer->getUnitPrice(); 
$totalPrice = $pricer->getTotalPrice(); 
$optionsPrice = $pricer->getOptionsPrice(); 

लेकिन मैं पता नहीं विशेष रूप से जिस तरह से सिद्धांत और डेटा संग्रह स्थान नियंत्रकों में पहुंचा जा सकता है Symfony/सिद्धांत का है कि अंदर कर रही है, के बारे में जाने के लिए कैसे कर सकते है।

उत्तर

29

आप सही हैं कि आपके पास अपने सभी पुनः उपयोग करने योग्य व्यवसाय तर्क को एक सेवा में बंद कर दिया जाना चाहिए ताकि विभिन्न नियंत्रक कोड का पुनः उपयोग कर सकें।

आप की जाँच "कैसे एक सेवा बनाने के लिए" प्रलेखन है:

Service Container Documentation

मैं तुम्हें गति संक्षिप्त जानकारी दी गई है, हालांकि दे देंगे।

कॉन्फ़िगरेशन में।YML आप अपनी सेवा परिभाषित करने की जरूरत:

namespace Acme\ProductBundle\Service; 

class PricingService { 

    private $doctrine;   

    function __construct($doctrine) { 
     $this->doctrine = $doctrine; // Note that this was injected using the arguments in the config.yml 
    } 

    // Now the rest of your functions go here such as "getUnitPrice" etc etc. 
} 

अन्त में एक नियंत्रक से अपनी सेवा प्राप्त करने के लिए आप बस की जरूरत है:

services: 
    pricing_service: 
     class: Acme\ProductBundle\Service\PricingService 
     arguments: [@doctrine] 

तो फिर तुम सिर्फ अपने सेवा का प्रतिनिधित्व करने के लिए एक दलदल मानक PHP वर्ग बनाने की जरूरत है कार्य करें:

$pricingService = $this->get('pricing_service');

अन्य तरीकों से इस तरह के config.yml में अपने सभी सेवाओं डंपिंग लेकिन यह सब नहीं के रूप में आप सेवा modularise कर सकते हैं दस्तावेज में समझाया गया है। यह भी ध्यान रखें कि आप अपनी सेवा में अपनी इच्छानुसार किसी भी अन्य सेवा को इंजेक्ट कर सकते हैं, इसलिए यदि आपको arguments: [@doctrine, @security.context, @validator] जैसी चीजों की आवश्यकता है तो आप यह सब कुछ कर सकते हैं या यहां तक ​​कि: [@my_other_service]

मुझे एंटिटी मैनेजर इंजेक्शन लगाने पर आपके अन्य प्रश्न से संदेह है कि आप पहले ही इसे प्राप्त कर सकते हैं, हालांकि यह जाने का तरीका था!

उम्मीद है कि यह अभी भी आपके लिए उपयोगी था!

+0

शानदार - धन्यवाद! आपकी प्रतिक्रिया और क्यूबा के बीच मुझे ऐप के इस हिस्से को पूरा करने का तरीका समझ गया है। – Nick

+0

क्या होगा यदि आप एक ही लेनदेन के तहत दो सेवा कॉल गठबंधन करना चाहते हैं? – GorillaApe

10

आपने अपना उदाहरण सरलीकृत किया है, इसलिए मुझे वास्तव में सभी विवरण नहीं पता हैं, लेकिन यहां आपकी समस्या का समाधान करने का मेरा प्रयास है।

ध्यान दें कि आपको वास्तव में एक सेवा की आवश्यकता हो सकती है लेकिन आपको मेरे उदाहरण के आधार पर विचार प्राप्त करना चाहिए।

मूल रूप से सिद्धांत का पालन करें - एक वर्ग में एक जिम्मेदारी है।

मूल्य कैलकुलेटर की गणना करता है कीमत:

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

नियंत्रक:

namespace MyNamespace; 

interface PriceInterface 
{ 
    public function getUnitPrice(); 

    public function getTotalPrice(); 

    public function getOptionsPrice(); 
} 

मूल्य कैलकुलेटर सेवा इकाई प्रबंधक पर एक निर्भरता है:

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

मूल्य PriceInterface द्वारा वर्णित है मूल्य प्राप्त करने के लिए मूल्य कैलकुलेटर सेवा का उपयोग करता है:

public function indexAction() 
{ 
    $priceCalculator = $this->get('my_namespace.price_calculator'); 
    $price = $priceCalculator->calculate(); 

    $unitPrice = $price->getUnitPrice(); 
    $totalPrice = $price->getTotalPrice(); 
    $optionsPrice = $price->getOptionsPrice(); 
} 

आप एक अनुरोध या अन्य सेवा आप उन्हें calculate() विधि को पैरामीटर के रूप डीआईसी या मैन्युअल का उपयोग कर इंजेक्षन कर सकते हैं की जरूरत है।

ध्यान दें कि मैं EntityManager इंजेक्शन PriceCalculator सेवा करने के लिए, लेकिन आप सेवाओं के रूप में डेटा प्रदाताओं को परिभाषित करने और (वास्तव में जटिल चीजों के लिए) के बजाय उन्हें इंजेक्षन सकता है।

आप सभी प्रश्नों को भंडारों में भी धक्का दे सकते हैं और इकाइयों को अपने प्राइसकलक्यूलेटर पर पास कर सकते हैं।

+0

यह, कसीन की प्रतिक्रिया के साथ संयुक्त, बहुत उपयोगी था। धन्यवाद! – Nick

संबंधित मुद्दे