Question

J'ai essentiellement une enquête qui est montrée, et les gens répondent à des questions beaucoup comme un test, et il y a différents chemins, c'est assez facile jusqu'à présent, mais je voulais le rendre plus dynamique, afin que je puisse avoir une règle générique qui est pour le test avec tous les chemins, pour rendre l'évaluateur plus facile à travailler actuellement. il suffit d'autoriser AND, et chaque OU devient essentiellement une autre règle de l'ensemble,

QuestionID, alors je forme un tas de règles ET comme

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

cette règle 1 dit que si les questions 123 et 124 reçoivent une réponse vraie et que 127, 128 sont fausses, elles passent. OU (règle 2) est que si 123 et 125 sont vrais et que 127 est faux, ils passent également. Cela devient fastidieux s’il ya beaucoup de combinaisons, donc je veux implémenter OU dans la logique, je ne suis pas sûr de la meilleure approche pour résoudre ce problème.

Je pense que le moteur de règles est trop compliqué, il doit y avoir un moyen plus simple, peut-être construire un graphique comme dans LINQ et ensuite évaluer pour voir s'ils passent,

merci!

- pas un majeur de compsci.

Était-ce utile?

La solution

Cela n’a pas à être compliqué: vous avez déjà presque terminé, car vos éléments et implémentent efficacement une règle de type AND. Je voudrais présenter un élément pouvant contenir des éléments.

En votre pouvoir, vous pourriez avoir:

  • Une classe RuleBase, avec un " public abstract bool Evaluate () " méthode
  • Les classes TrueRule, FalseRule et OrRule, qui contiennent des listes d'objets RuleBase
  • Une classe QuestionRule, qui fait référence à une question spécifique

Vous devez implémenter la méthode d'évaluation sur chacun de ces éléments, comme suit:

  • TrueRule: ne renvoie true que si toutes les règles contenues renvoient true à partir de l'évaluation
  • FalseRule: ne renvoie true que si toutes les règles contenues renvoient false depuis Evaluate
  • OrRule: renvoie true si au moins une des règles contenues renvoie true à partir de l'évaluation
  • QuestionRule: renvoie la réponse à la question initiale

Cette hiérarchie de classes implémente un simple arbre de syntaxe abstraite (AST). LINQ, sous la forme de la classe System.Expressions.Expression, fait à peu près la même chose, mais il est utile d’écrire la vôtre si ce n’est pas évident de voir comment tout va bien.

Autres conseils

Si vous utilisez un moteur de règles approprié prenant en charge l'inférence, il sera plus efficace et plus extensible.

Consultez le http://www.flexrule.com , qui est un moteur de règles souple et extensible qui prend en charge trois types de règle. Les règles de procédure, d'inférence et de règles peuvent être externalisées à partir de votre application et exécutées à l'aide de ce cadre.

Je ne suis pas sûr de bien comprendre le problème que vous essayez de résoudre, mais vous pouvez utiliser un simple XPath pour obtenir les identifiants:

Cela vous donnerait tous les & "vrais &"; ID où l'ID de la règle = 1: / règle [@id = & "1 &";] / true // @ ID

Comme ci-dessus seulement, il vous donne les faux identifiants: / rule [@id = " 1 "]] / false // @ ID

Enfin un lien vers une introduction à XPath dans .NET http://www.developer.com/xml/article.php/3383961

Bonne chance

Je suggérerais de mettre les réponses aux questions plutôt que d'utiliser true et false pour regrouper les questions. Je pense que cela rend XML plus facile à lire, ce qui est discutable. Ce qui n’est pas discutable, c’est que cela permet d’évaluer un élément question indépendamment, c’est-à-dire sans aucune connaissance du contexte dans lequel vous essayez de l’évaluer. Cela simplifie le code.

Je prendrais également une page de XML Schema et implémenterais votre logique OR en tant qu'élément choice. Un élément bool GetProvidedAnswer(int questionID) est vrai si l'un de ses enfants est vrai. Vous pouvez bien sûr les imbriquer:

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

Cela vous laisse avec quatre méthodes assez simples à mettre en œuvre, chacune étant utilisée par celle qui la précède:

  • bool IsQuestionCorrect(XmlElement question)
  • bool IsChoiceCorrect(XmlElement choice)
  • bool IsRuleSatisfied(XmlElement rule)
  • List<XmlElement>

La structure du XML facilite la mise en oeuvre de ces méthodes:

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

Il peut être intéressant d’ajouter un IsFooCorrect aux paramètres des méthodes <=>. (Si le moteur de règles est dans une classe, vous pouvez en faire un champ de classe.) Assurez-vous que toutes les méthodes ajoutent l'élément actuel à la liste lorsqu'une réponse est fausse. Vous pouvez ensuite examiner le contenu de cette liste pour savoir exactement pourquoi une règle a échoué.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top