【问题标题】:Is this a violation of the single responsiblity principle?这是否违反了单一责任原则?
【发布时间】:2009-09-12 23:24:41
【问题描述】:

我有如下方法和接口:

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 似乎是一个不错的折衷方案。

这样的场景是特定/主观的,还是真的有最佳实践可以在这里应用?

【问题讨论】:

  • List 参数可以是 IEnumerable

标签: single-responsibility-principle cohesion


【解决方案1】:

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

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

public interface IRule {
    object EvaluateExpression();
}

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案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);
           }
      
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多