我在DB(question
和answer
)中有2个表。一个问题有很多答案。
我得到一些Answers
和取决于question.type
我准备的结果阵列。
在没有任何框架应用程序我有Factory
类回特定对象(SingleChoiceQuestion
,OpenQuestion
,MultipleChoiceQuestion
)取决于question.type
从DB。所有Questions
扩展抽象类Question
已申报abstract
方法getResults
。所有类型都有自己的业务逻辑准备的结果。
因此,在这种情况下,当我按工厂创建对象时,我正在使用方法,getResults
并且一切正常。
我想在Symfony的创建它,我阅读文档。在我看来,我应该为我的所有服务Question
类型。
我已经创建AggregatedResultsManager
与方法generate
返回结果的数组。取决于question.type
它调用getResults
的具体方法service
。
我想补充一点,我无法更改数据库结构。
我的问题:
services
吗?如果我这样做不对,请大家帮我理解它,并告诉我的正确途径。AggregatedResultsManager
约18种问题。在每项服务中,我需要创建switch
18种选择,如何防止这种情况发生?
switch ($this->question->getType()) {
case Question::SINGLE:
$results = $this->container->get('app.single_choice_question')->getResults($answers);
break;
// other types
}
我有一些想法,以创建类型和服务名称数组:
$services = [
Question::SINGLE => 'app.single_choice_question',
Question::MULTIPLE => 'app.multiple_choice_question',
Question::OPEN => 'app.open_question',
];
然后像每个服务使用它:
$results = $this->container->get($services[$this->question->getType()])->getResults($answers);
我认为这是不使用18种选择的开关的最佳方法。但我会需要阵列硬编码的服务名称。
我的代码:
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 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;
}
}
结果
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 is 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;
}
}
控制者
public function questionIdsAction(Question $question)
{
$resultsManager = $this->get('app.agreggated_results_manager');
$resultsManager->setQuestion($question);
$results = $resultsManager->generate();
return new JsonResponse($results);
}
我想你说你有18个QuestionTypes所有延伸的需要实体管理器做的工作的AbstractQuestion?而不是让18个服务,然后使用容器我会建议作出的一个问题工厂:
class QuestionFactory
public function __construct($entityManager)
$this->entityManager = $entityManager;
public function create($questionType)
switch($questionType) {
case Question::SINGLE: return new SingleQuestion($this->entityManager);
这样,你会注入到工厂,结果经理。
这种方法避免了需要创建一批服务,并需要通过周围的容器。您仍然有一个switch语句,但是没关系。
可能出现的唯一的问题是,如果某个QuestionTypes需要额外的依赖。在这种情况下,你可能会重新使用的服务。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句