Вопрос

У меня есть следующий метод и интерфейс:

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

Поскольку правила имеют приоритет, они фактически никогда не должны обрабатываться не по порядку. Это приводит меня (я думаю) к трем решениям:

<Ол>
  • Сортируйте правила перед передачей их в оценщик.
  • Измените тип параметра на такой, который обеспечивает порядок сортировки.
  • Сортировка в оценщике.
  • Мне нравится вариант 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