我在DB中有2个表(question
和answer
)。一个问题有很多答案。Symfony2服务
我得到一些Answers
并取决于question.type
我准备结果数组。
在没有任何框架应用程序我有Factory
类从DB返回特定对象(SingleChoiceQuestion
,OpenQuestion
,MultipleChoiceQuestion
)取决于question.type
。所有Questions
扩展了抽象类Question
,该类已声明abstract
方法getResults
。所有类型都有自己的业务逻辑来准备结果。
所以在这种情况下,当我用工厂创建对象时,我使用方法getResults
,一切正常。
我想在Symfony中创建它并阅读文档。在我看来,我应该为我所有的Question
类型创建服务。
我创建了AggregatedResultsManager
,其中方法generate
返回结果数组。取决于question.type
它从特定的service
调用getResults
方法。
我想补充说,我不能改变DB结构。
我的问题:
- 上午我创建和使用
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种选择的开关。但是我需要硬编码数组中的服务名称。
我的代码:
服务。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);
}
很难找出问题所在。甚至可能超过一个?如果你没有得到任何有用的答案,你可能会考虑尝试简化一些事情。 – Cerad
@Cerad你是对的!我看到他问的唯一真正的问题是:“我是否正在创建和使用服务?” –
@Cerad谢谢各位反馈。我添加了问题。 – wtk13