我有以下方法和界面:

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. 在评估者中排序。
  4. 我喜欢选项3,因为它总是确保它被排序,我喜欢选项1,因为它看起来更具凝聚力。选项2似乎是一个很好的妥协。

    这种情境是特定的/主观的,或者是否真的有最佳实践在这里应用?

有帮助吗?

解决方案

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

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

public interface IRule {
    object EvaluateExpression();
}

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

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

其他提示

我的选择将用于选项3.为了尽量减少耦合,您需要确保不要对发送到函数中的数据做太多假设。

如果一个不同的类要在以后使用它,你会认为他们知道按优先顺序排序吗?

在这样的场景中,我会做类似的事情:

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

}

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top