Pergunta

Eu tenho essencialmente uma pesquisa que é mostrado, e as pessoas responder a perguntas muito como um teste, e há diferentes caminhos, é muito fácil até agora, mas eu queria torná-lo mais dinâmico, para que eu possa ter uma regra genérica que é para o teste com todos os caminhos, para fazer o avaliador mais fácil trabalhar com atualmente i apenas permitir e é, e cada um OR torna-se essencialmente uma outra regra no conjunto,

QuestionID, então i formar um monte de e regras gosta assim

<rule id="1">
<true>
 <question ID=123>
 <question ID=124>
</true>
<false>
 <question ID=127>
 <question ID=128>
</false>
</rule>
<rule id="2"><true>
 <question ID=123>
 <question ID=125>
</true>
<false>
 <question ID=127>
</false>
</rule>

essa regra 1 diz que se pergunta 123, e 124 são respondidas verdadeiro, e 127, 128 são falsas, eles passam. OR (regra 2) é se 123 e 125 são verdadeiras e 127 é falso, passam bem. Isto torna-se tedioso se há muitas combinações, assim que eu quero implementar ou na lógica, eu não sou apenas certo o que melhor abordagem é para este problema.

Eu acho que as regras motor é muito complicado, deve haver uma maneira mais fácil, talvez construindo um gráfico como em LINQ e depois avaliar para ver se eles passam,

Obrigado!

-. Não um compsci importante

Foi útil?

Solução

Isto não tem de ser complicado: você está a maior parte do caminho já, uma vez que seus e elementos efetivamente implementar uma regra do tipo E. Eu iria introduzir um elemento que pode segurar e elementos.

Em seu poderia, você poderia ter:

  • class uma base de regra, com um "bool abstrato público Evaluate ()" método
  • TrueRule, FalseRule e OrRule classes, que contêm listas de ruleBase objetos
  • Um QuestionRule classe, que se refere a uma pergunta específica

Você iria implementar o método Avaliar em cada um deles como se segue:

  • TrueRule: retorna true somente se todas as regras contidas retornar verdadeiro do Avaliar
  • FalseRule: retorna true somente se todas as regras contidas retornar falso do Avaliar
  • OrRule: retorna verdadeiro se pelo menos uma das regras constantes retornos verdadeiro do Avaliar
  • QuestionRule: retorna a resposta para a pergunta original

Essa classe implementa hierarquia de uma árvore de sintaxe abstrata simples (AST). LINQ, na forma da classe System.Expressions.Expression, faz praticamente a mesma coisa, mas é útil para escrever o seu próprio, se não é óbvio como tudo se encaixa.

Outras dicas

Se você usar um motor de regras adequado que suporta inferência seria mais eficiente e extensível.

Dê uma olhada http://www.flexrule.com que é, um motor flexível regra extensível que suporta três tipos de regra. , regras de inferência e Estado-Flow processuais podem ser exteriorizado de sua aplicação e são executadas usando este quadro.

Eu não tenho certeza eu entendo totalmente o problema que você está tentando resolver, mas você poderia usar um XPath simples para chegar a do ID:

Isto lhe daria todo o "verdadeiro" ID é onde o ID regra = 1: / Rule [@ id = "1"] / true // @ ID

O mesmo que acima somente dá-lhe a identidade falsa de: / Rule [@ id = "1"] / false // @ ID

Por fim um link para uma introdução à XPath no .NET http://www.developer.com/xml/article.php/3383961

Good Luck

Eu sugiro colocar as respostas sobre as questões, em vez de usar true e false para agrupar as perguntas. Eu acho que ele faz para XML que é mais fácil de ler, o que é discutível. O que não é discutível é que ele torna possível avaliar um elemento question de forma independente, ou seja, sem qualquer conhecimento do contexto em que você está tentando avaliá-lo. Isso faz de código mais simples.

Eu também tomar uma página do XML Schema e implementar sua lógica OR como um elemento choice. Um elemento choice é verdadeiro se qualquer um dos seus filhos são verdadeiras. Você pode, é claro, o ninho deles:

<rule id="1">
   <question id="123" answer="true" />
   <question id="124" answer="false" />
   <choice id="1">
      <question id="125" answer='true' />
      <choice id="2">
         <question id="126" answer='false' />
         <question id="127" answer='false' />
      </choice>
   </choice>
</rule>

Isso você folhas com quatro métodos muito simples de implementar, cada um dos quais é usado pela anterior:

  • bool GetProvidedAnswer(int questionID)
  • bool IsQuestionCorrect(XmlElement question)
  • bool IsChoiceCorrect(XmlElement choice)
  • bool IsRuleSatisfied(XmlElement rule)

A estrutura do XML torna esses métodos muito simples de implementar:

 bool IsRuleSatisfied(XmlElement rule)
 {
    bool satisfied = true;
    foreach (XmlElement child in rule.SelectNodes("*"))
    {
       if (child.Name == "question")
       {
          satisfied = satisfied && IsQuestionCorrect(child);
       }
       if (child.Name == "choice")
       {
          satisfed = satisfied && IsChoiceCorrect(child);
       }
       if (!satisfied)
       {
          return false;
       }
   }
   return true;
}

Pode valer a pena adicionar um List<XmlElement> para os parâmetros dos métodos IsFooCorrect. (Se o mecanismo de regras está em uma classe, você pode torná-lo um campo de classe.) Faça `todos os métodos de adicionar o elemento atual para a lista quando errada de uma resposta. Você pode então examinar o conteúdo dessa lista para saber exatamente por que uma regra falhou.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top