Como funciona em teoria um sistema de regras como o usado no Outlook Express?Como poderia ser feito?

StackOverflow https://stackoverflow.com/questions/2043546

  •  19-09-2019
  •  | 
  •  

Pergunta

Estou curioso sobre isso:

No Outlook Express da Microsoft (ou Outlook, não me lembro bem, sou usuário de Mac), eles têm algo muito legal.Regras genéricas:

Você pode configurar um conjunto de regras para classificar ou excluir automaticamente seus e-mails, por exemplo.É incrivelmente poderoso e fácil de usar.

Essas regras eram mais ou menos assim:

"Se o e-mail na caixa de entrada tiver um assunto que contenha 'foo', ou 'bar', ou 'foobar', exclua-o"

Preciso codificar algo semelhante para um poderoso sistema de validação de formulários.O desenvolvedor deve simplesmente ser capaz de criar regras como esta:

rule: [password_1] is_not_equal_with [password_2]
consequence: show_error '2921'

rule: [firstName] has_less_characters_than '2'
consequence: show_error '1211'

rule: [age] is_numeric, is_smaller_than '13', is_greater_than '130'
consequence: show_error '1522'

rule: [gender] is_equal_with 'female'
consequence: show_group [female_questions]

rule: [termsAndConditionsAccepted] is_not_checked
consequence: show_error '482'

rule: [age] is_less_than 21
consequence: hide_group [income_questions]

Bem, tenho algumas idéias de como isso pode ser feito e as postarei aqui como resposta.Mas antes de reinventar a roda:Há algum conceito escrito que eu possa usar como base para desenvolver um sistema de validação baseado em regras semelhante a este?Ou se não, você tem alguma sugestão de como isso poderia ser feito?

No exemplo acima, tudo entre colchetes é o nome de um elemento de formulário HTML.Tudo entre apóstrofos '' é um valor "codificado" para comparação.

As regras definidas são traduzidas em código PHP E código JavaScript para fazer a validação do lado do cliente e do servidor.

Recursos dos quais isso deve ser capaz:

  • Regras condicionais:Algo A depende de algo B
  • Comparações de valores:Para números inteiros, flutuantes, strings
  • Habilite também alguma lógica de controle de formulário, como no exemplo "[gender] is_equal_with 'female'" acima.

Como isso poderia ser feito?Quais são as entidades que devo considerar, do ponto de vista científico?

Acho que o conceito teórico disso é independente de plataforma.Embora eu implemente isso em PHP e JavaScript, não há razão para que um dev C ++ não deva responder ;-) (Eu sou um cara-C, btw)

Foi útil?

Solução

Você pode querer verificar alguns dos mecanismos de regras de código aberto;ou até mesmo pago por um.

Exemplos incluem
Pagar por isso:
InRule, Mecanismo de regras de negócios, Mecanismo de regras de negócios ASA

Código aberto:
Regras abertas, Baba

Tem muito mais.Incluindo alguns integrados ao java (Java Rule Engine API (JSR94)) e .Net (Windows Workflow Foundation Rules Engine).

Não tenho certeza sobre PHP direto.

Como observação lateral, usei alguns motores, como Regras de Haley (antes de serem comprados pela Oracle) para conduzir UIs da web.Esteja ciente de que a velocidade de execução é absolutamente crítica.Haley processava cerca de 2.000 regras por carregamento de página (aplicativo de hipoteca) e estava sendo executado em menos de 40 ms (não é um erro de digitação).Nós o usamos para decidir quais campos estavam na página, bem como determinar se os dados inseridos eram consistentes, atendiam aos padrões legais e até mesmo se foram inseridos corretamente.

Alguns dos outros mecanismos eram muito mais lentos, mesmo em conjuntos de regras muito menores, devido ao tempo que levava para simplesmente instanciar os mecanismos.

Também segui o caminho de escrever o meu próprio para sistemas menores.No meu caso usei javascript e simplesmente configurei variáveis ​​com dados da página postada antes de executar os scripts que foram salvos com os formulários.

Isso também teve desempenho em uma escala menor, mas limitei-o a fornecer apenas respostas simples de sim / não.

Outras dicas

Para um pequeno número de regras e mensagens, você pode aplicar um algoritmo de força bruta: pegue cada regra e cada mensagem e compare se eles se encaixam. Você vai chegar a um o (rm) Complexidade em que R é o número de regras e M é o número de mensagens, não considerando que uma regra pode ter várias condições.

Para um grande número de regras ou mensagens, você pode implementar uma rede RETE (http://en.wikipedia.org/wiki/rete_algorithm). Isso exige alguma memória, mas é muito mais rápido na prática. Dependendo da maneira como você projeta suas regras, você obterá complexidades diferentes.

A primeira abordagem é simples e acho que não preciso explicar. No entanto, se você precisar de ajuda, avise -me e eu detalharei essa ideia. Deixe -me explicar a segunda abordagem:

Leia um pouco sobre o algoritmo RETE antes de ir mais longe.

Na parte alfa da rede RETE, você armazenará condições distintas que aparecem em suas regras. Algumas regras podem compartilhar algumas condições. Curti:

Regra 1: Se (message.date é igual a 24.10.2009) e (message.title contém "olá"), faça algo1

Regra2: Se (message.hasattachement for verdadeiro) e (message.date é igual a 24.10.2009), faça algo2

Portanto, a parte alfa da rede terá 3 elementos

  • C1: (message.date é igual a 24.10.2009)
  • C2: (message.title contém "hello")
  • C3: (message.hasattachement é verdadeiro)

Na rede beta, você terá dois nó de junção que o link C1-C2 e C3-C1.

Os nós de produção que encerram a rede beta conterão a série de ações que devem ser executadas quando uma mensagem satisfaz todas as condições da regra (na parte alfa) e todas as verificações de consistência (na parte beta).

A parte mais complicada é a rede beta. Se você deseja apenas o lógico e em suas regras (nenhuma outra opção lógica ou parênteses) é trivial. No entanto, se você deseja construções mais complicadas, terá que escrever muito código e fazer muitos testes.

Para mais informações sobre rete:

  • Combinação de produção para grandes sistemas de aprendizado /-Robert B. Doorenbos. (1995)
  • Sobre a implementação eficiente de sistemas de produção /- Charles L. Forgy (1979)

Em um design orientado a objetos, uma abordagem é implementar o padrão de comando ou, para necessidades mais complexas, o padrão de intérprete. Você normalmente criaria várias classes para diferentes categorias de regras e as compõe para cenários mais complexos (por criar compositério, por exemplo); Todos eles suportam uma interface como Execute () ou Execute (contexto).

Você constrói uma fila de instâncias de regra e chama Execute (contexto) em cada um deles para cada objeto. O contexto contendo uma instância do objeto (mensagem, formulário, ou qualquer outra coisa) sobre o qual você está agindo.

Encadear as regras em um cadeia de responsabilidade.

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