0

我有以下方法和接口:

public object ProcessRules(List<IRule> rules)
{
    foreach(IRule rule in rules)
    {
        if(EvaluateExpression(rule.Exp) == true) return rule.Result;
    }

    //Some error handling here for not hitting any rules
}

public interface IRule
{
    Expression Exp;
    Object Result;
    int Precedence;
}

因为规则具有优先级,所以它们实际上不应该被乱序处理。这导致我(我认为)三个解决方案:

  1. 在将规则传递给评估器之前对其进行排序。
  2. 将参数类型更改为强制排序顺序的东西。
  3. 在评估器中排序。

我喜欢选项 3,因为它始终确保它是有序的,我喜欢选项 1,因为它看起来更有凝聚力。选项 2 似乎是一个很好的折衷方案。

像这种上下文这样的场景是特定的/主观的,还是真的有一个最佳实践可以在这里应用?

4

3 回答 3

4

我认为这更像是违反了德墨忒耳法则和封装。EvaluateExpression 看起来像是属于规则。考虑一下:

public object ProcessRules(List<IRule> rules) {
    foreach(IRule rule in rules) {
        return rule.EvaluateExpression();
    }
}

public interface IRule {
    object EvaluateExpression();
}

这样您就不必暴露规则的内部结构,例如 Exp 或 Result。

是的,如果您想要的行为是按优先顺序评估规则,那么请确保对它们进行排序。规则的职责是评估自身,而调用者决定以什么顺序评估它们。

于 2009-09-12T23:34:30.050 回答
0

我会投给选项 3。为了尽量减少耦合,您要确保不要对发送到函数的数据做出太多假设。

如果以后有不同的班级使用它,您会假设他们知道按优先级排序传递它们吗?

于 2009-09-12T23:33:26.150 回答
0

在这样的情况下,我会做类似的事情:

public class RuleProcessor
{   
     public void SortRules(List<IRule> rules){}

     //You could make this an abstract method
     public object ProcessSortedRules(List<IRule> rules)
     {
         foreach(IRule rule in rules)
         {
             if(EvaluateExpression(rule.Exp) == true) return rule.Result;
         }

     //Some error handling here for not hitting any rules

     }

     public object ProcessRules(List<IRule> rules)
     {
          SortRules(rules);
          ProcessSortedRules(rules);
     }

}

您可以将其设为抽象类或其他类聚合的某种功能。

于 2009-09-12T23:43:29.330 回答