Pergunta

Eu tenho o seguinte método e interface:

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

Como as regras têm uma precedência, eles devem realmente não ser processadas fora de ordem. Isto leva-me com (eu acho) três soluções:

  1. Classificar regras antes de passá-los para o avaliador.
  2. Alterar o tipo de parâmetro para algo que impõe uma ordem de classificação.
  3. Classificar dentro do avaliador.

Eu como opção 3 porque sempre garante que ele é ordenado e eu como opção 1 porque parece mais coesa. E a opção 2 parece ser um bom compromisso.

É um cenário como este contexto específico / subjetiva, ou há realmente uma boa prática a ser aplicada aqui?

Foi útil?

Solução

Eu acho que é mais como uma violação da Lei de Demeter e encapsulamento. O EvaluateExpression parece que pertence em regras. Considere o seguinte:

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

public interface IRule {
    object EvaluateExpression();
}

Dessa forma, você não tem que expor o funcionamento interno de regras, como Exp ou resultado.

E sim, se o comportamento desejado é que as regras ser avaliadas a fim de precedência, em seguida, garantir que eles são ordenados. A responsabilidade do governo é avaliar em si, embora seja a decisão do chamador em que ordem para avaliá-los.

Outras dicas

Meu voto iria para a opção 3. Em um esforço para minimizar o acoplamento, você quer ter certeza de que você não fazer muitas suposições sobre os dados enviados em uma função.

Se uma classe diferente fosse fazer uso deste em uma data posterior, se você assumir que eles sabem para passá-las classificadas segundo a precedência?

Em um cenário como este que eu faria algo como:

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

}

Você poderia fazer que uma classe abstrata ou algum tipo de funcionalidade outras classes agregar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top