php - Symfony2 service -


i have 2 tables in db (question , answer). 1 question has many answers.

i answers , depends on question.type prepare results array.

in app without framework have factory class return specific object (singlechoicequestion, openquestion, multiplechoicequestion) depends question.type db. questions extends abstract class question has declared abstract method getresults. types have own business logic prepare results.

so in situation when have created object factory i'm using method getresults , works well.

i create in symfony , read documentation. in opinion should create services question types.

i have created aggregatedresultsmanager method generate returns results array. depends on question.type calls getresults method specific service.

i add, can't change db structure.

my questions:

  1. am creating , using services right? if wrong, please me understanding , show me right way.
  2. i have several services aggregatedresultsmanager , 18 question types.

in each service need create switch 18 choices, how prevent that?

switch ($this->question->gettype()) {     case question::single:         $results = $this->container->get('app.single_choice_question')->getresults($answers);         break;     // other types } 

i have idea create array types , service names:

$services = [     question::single => 'app.single_choice_question',     question::multiple => 'app.multiple_choice_question',     question::open => 'app.open_question', ]; 

and use in each service that:

$results = $this->container->get($services[$this->question->gettype()])->getresults($answers); 

i think it's best way not use switch 18 choices. need hardcode service names in array.

my code:

services.yml

app.question:     class: appbundle\questions\question     abstract: true     arguments: ['@doctrine.orm.entity_manager']  app.single_choice_question:     class: appbundle\questions\singlechoice     parent: app.question  app.agreggated_results_manager:     class:  appbundle\results\aggregatedresultsmanager     arguments: ['@doctrine.orm.entity_manager', '@service_container'] 

abstract question

abstract class question {     /**      * @var entitymanager      */     protected $em;      public function __construct(entitymanager $em)     {         $this->em = $em;     }      abstract public function getresults($answers); } 

singlechoice

class singlechoice extends question {     public function getresults($answers)     {         $results = [];          // business logic          return $results;     } } 

results

class aggregatedresultsmanager {     /**      * @var entitymanager      */     private $em;      /**      * @var question      */     private $question;      /**      * @var containerinterface      */     private $container;      public function __construct(entitymanager $em, containerinterface     $container)     {         $this->em = $em;         $this->container = $container;     }      public function generate()     {         if (!$this->question) {             throw new \logicexception('question not set');         }          $answers = $this->em             ->getrepository('appbundle:answer')             ->findby(['question' => $this->question]);          $results = [];          if (empty($answers)) {             return $results;         }          switch ($this->question->gettype()) {             case question::single:                 $results = $this->container->get('app.single_choice_question')->getresults($answers);                 break;             // other types         }          return $results;     }       public function setquestion(question $question)     {         $this->question = $question;     } } 

controller

public function questionidsaction(question $question) {     $resultsmanager = $this->get('app.agreggated_results_manager');     $resultsmanager->setquestion($question);     $results = $resultsmanager->generate();      return new jsonresponse($results); } 

i think saying have 18 questiontypes extending abstractquestion needs entity manager it's work? instead of making 18 services , using container suggest making question factory:

class questionfactory     public function __construct($entitymanager)         $this->entitymanager = $entitymanager;     public function create($questiontype)         switch($questiontype) {             case question::single: return new singlequestion($this->entitymanager); 

you inject factory results manager.

this approach avoids need create bunch of services , of needing pass around container. still have switch statement okay.

the problems might arise if questiontypes need additional dependencies. in case might using services.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -