Pergunta

Estou auditando um projeto que usa o que é chamado de Mecanismo de regras.Resumindo, é uma forma de externalizar a lógica de negócios do código da aplicação.

Este conceito é totalmente novo para mim e sou bastante cético quanto a isso.Depois de ouvir as pessoas falarem sobre Modelos de domínio anêmico nos últimos anos, tenho questionado a abordagem do mecanismo de regras.Para mim, eles parecem uma ótima maneira de FRAQUECER um modelo de domínio.Por exemplo, digamos que estou fazendo um webapp java interagindo com um mecanismo de regras.Então decido que quero ter um aplicativo Android baseado no mesmo domínio.A menos que eu queira que o aplicativo Android também interaja com o mecanismo de regras, terei que perder qualquer lógica de negócios que já tenha sido escrita.

Como ainda não tenho nenhuma experiência com eles, apenas curiosidade, fiquei interessado em saber os prós e os contras de usar um Rules Engine?A única vantagem que consigo pensar é que você não precisa reconstruir todo o seu aplicativo apenas para alterar alguma regra de negócios (mas, na verdade, quantos aplicativos realmente têm tantas alterações?).Mas usar um mecanismo de regras para resolver esse problema me parece como colocar um curativo sobre um ferimento de arma de fogo.

ATUALIZAÇÃO - desde que escrevi isto, o próprio deus, Martin Fowler, blogou sobre o uso de um mecanismo de regras.

Foi útil?

Solução

A maioria dos mecanismos de regras que vi são vistos como uma caixa preta pelo código do sistema.Se eu fosse construir um modelo de domínio, provavelmente desejaria que certas regras de negócios fossem intrínsecas ao modelo de domínio, por exemplo.regras de negócios que informam quando um objeto possui valores inválidos.Isto permite que vários sistemas compartilhem o modelo de domínio sem duplicar a lógica de negócios.Eu poderia fazer com que cada sistema usasse o mesmo serviço de regras para validar meu modelo de domínio, mas isso parece enfraquecer meu modelo de domínio (como foi apontado na pergunta).Por que?Porque, em vez de aplicar consistentemente minhas regras de negócios em todos os sistemas em todos os momentos, confio nos programadores do sistema para determinar quando as regras de negócios devem ser aplicadas (chamando o serviço de regras).Isso pode não ser um problema se o modelo de domínio chegar completamente preenchido, mas pode ser problemático se você estiver lidando com uma interface de usuário ou sistema que altera valores no modelo de domínio ao longo de sua vida útil.

Existe outra classe de regras de negócios:tomando uma decisão.Por exemplo, uma companhia de seguros pode precisar classificar o risco de subscrever um requerente e chegar a um prémio.Você poderia colocar esses tipos de regras de negócios em seu modelo de domínio, mas uma decisão centralizada para cenários como esse geralmente é desejável e, na verdade, se encaixa muito bem em uma arquitetura orientada a serviços.Isso levanta a questão de por que um mecanismo de regras e não um código de sistema.O local onde um mecanismo de regras pode ser uma escolha melhor é onde as regras de negócios responsáveis ​​pela decisão mudam ao longo do tempo (como apontaram algumas outras respostas).

Os mecanismos de regras geralmente permitem que você altere as regras sem reiniciar o sistema ou implantar um novo código executável (independentemente das promessas que você receber de um fornecedor, certifique-se de testar suas alterações em um ambiente que não seja de produção, porque, mesmo que o mecanismo de regras seja perfeito , os humanos ainda estão mudando as regras).Se você está pensando: “Posso fazer isso usando um banco de dados para armazenar valores que mudam”, você está certo.Um mecanismo de regras não é uma caixa mágica que faz algo novo.Pretende ser uma ferramenta que forneça um nível mais alto de abstração para que você possa se concentrar menos em reinventar a roda.Muitos fornecedores vão além, permitindo que você crie modelos para que os usuários corporativos possam preencher os espaços em branco em vez de aprender uma linguagem de regras.

Um aviso de despedida sobre modelos:os modelos nunca podem levar menos tempo do que escrever uma regra sem um modelo porque o modelo deve, no mínimo, descrever a regra.Planeje um custo inicial mais alto (o mesmo que se você construísse um sistema que usasse um banco de dados para armazenar valores que mudam vs.escrever as regras diretamente no código do sistema) - o ROI ocorre porque você economiza na manutenção futura do código do sistema.

Outras dicas

Eu acho que suas preocupações com os modelos de domínio anêmico são válidas.

Vi duas aplicações de um conhecido mecanismo de regras comerciais de retela em produção onde trabalho. Eu consideraria um um sucesso e o outro um fracasso.

O aplicativo bem -sucedido é um aplicativo de árvore de decisão, composto por ~ 10 árvores de ~ 30 pontos de ramificação cada. O mecanismo de regras possui uma interface do usuário que permite que as pessoas de negócios mantenham as regras.

O aplicativo menos bem -sucedido possui ~ 3000 regras entradas em um banco de dados de regras. Ninguém tem idéia se houver regras conflitantes quando uma nova é adicionada. Há pouco entendimento do algoritmo rete, e a experiência com o produto deixou a empresa, por isso se tornou uma caixa preta que é intocável e não refletorável. O ciclo de implantação ainda é afetado pelas alterações das regras - um teste de regressão completo deve ser feito quando as regras são alteradas. A memória também era um problema.

Eu pisava levemente. Quando um conjunto de regras é modesto em tamanho, é fácil entender mudanças, como a amostra simplista de e-mail fornecida acima. Uma vez que o número de regras suba nas centenas, acho que você pode ter um problema.

Eu também me preocuparia com o mecanismo de regras se tornar um gargalo singleton em sua inscrição.

Não vejo nada de errado em usar objetos como uma maneira de particionar que governa o espaço do motor. Incorporar o comportamento em objetos que adiam a um mecanismo de regras privadas parece bom para mim. Os problemas atingirão você quando o mecanismo de regras exigir estado que não faz parte de seu objeto para disparar corretamente. Mas esse é apenas mais um exemplo de design sendo difícil.

Os mecanismos de regra podem oferecer muito valor, em certos casos.

Primeiro, muitos motores de regra funcionam de uma maneira mais declarativa. Um exemplo muito grosseiro seria estranho, onde você pode atribuir regexes a blocos de código. Quando o regex é visto pelo scanner de arquivo, o bloco de código é executado.

Você pode ver que, neste caso, se você tivesse, digamos, um grande arquivo AWK e queria adicionar mais uma "regra", pode prontamente ir para a parte inferior do arquivo, adicionar você regex e lógica e ser feito com isto. Especificamente, para muitos aplicativos, você não está particularmente preocupado com o que as outras regras estão fazendo, e as regras não realmente interoperam entre si.

Assim, o arquivo AWK se torna mais como uma "sopa de regras". Essa natureza de "sopa de regra" permite que as pessoas se concentrem muito firmemente em seu domínio, com pouca preocupação com todas as outras regras que podem estar no sistema.

Por exemplo, Frank está interessado em ordens com um total de mais de US $ 1000, então ele coloca no sistema de regras que está interessado. "Se Order.Total> 1000, envie um email para Frank".

Enquanto isso, Sally quer todas as ordens da costa oeste: "Se Order.Source == 'West_coast' e envie um email para Sally".

Portanto, você pode ver neste caso trivial e artificial que uma ordem pode satisfazer as duas regras, mas ambas as regras são independentes uma da outra. Um pedido de US $ 1200 da costa oeste notifica Frank e Sally. Quando Frank não estiver mais preocupado, ele simplesmente arranca sua regra da sopa.

Para muitas situações, essa flexibilidade pode ser muito poderosa. Também pode, como este caso, ser exposto a usuários finais para obter regras simples. Usando expressões de alto nível e talvez script leves.

Agora, claramente, em um sistema complicado, existem todos os tipos de inter -relações que podem acontecer, é por isso que todo o sistema não é "feito com regras". Alguém, em algum lugar, estará encarregado das regras que não ficam fora de controle. Mas isso não diminui necessariamente o valor que um sistema pode fornecer.

Lembre -se de que isso nem sequer entra em coisas como sistemas especializados, onde as regras disparam sobre dados que as regras podem criar, mas um sistema de regras mais simples.

De qualquer forma, espero que este exemplo mostre como um sistema de regras pode ajudar a aumentar um aplicativo maior.

O maior profissional que eu já vi para os motores de regras é que ele permite que os proprietários de regras de negócios implementem as regras de negócios, em vez de colocar o ônus dos programadores. Mesmo se você tiver um processo ágil, onde está constantemente obtendo feedback das partes interessadas e passando por iterações rápidas, ele ainda não alcançará o nível de eficiência que pode ser alcançado com as pessoas que as regras de negócios também as implementam.

Além disso, você não pode subestimar o valor na remoção do ciclo recompile-reteste-redeploy que pode resultar de uma simples mudança de regra, se as regras estiverem incorporadas no código. Muitas vezes, existem várias equipes envolvidas em colocar a bênção em uma construção, e o uso de um mecanismo de regras pode tornar grande parte disso desnecessário.

Eu escrevi um mecanismo de regras para um cliente. A maior vitória foi incluir todas as partes interessadas. O motor pode executar (ou repetir) uma consulta e explicar o que estava acontecendo no texto. As pessoas de negócios podem olhar para a descrição do texto e apontar rapidamente nuances em regras, exceções e outros casos especiais. Depois que o lado comercial estava envolvido, a validação ficou muito melhor, porque era fácil obter suas contribuições. Além disso, o mecanismo de regras pode viver separadamente de outras partes de uma base de código de aplicativo para que você possa usá -lo nos aplicativos.

O golpe é que alguns programadores não gostam de aprender muito. Os mecanismos de regra e as regras que você coloca neles, juntamente com as coisas que os implementam, podem ser um pouco peludos. Embora um bom sistema possa lidar facilmente com teias de lógica doentes e torcidas (ou ilógicas com frequência;), não é tão simples quanto codificar um monte de if Declarações (não importa o que alguns dos motores de regras de mente simples façam). O mecanismo de regras fornece as ferramentas para lidar com os relacionamentos das regras, mas você ainda precisa imaginar tudo isso em sua mente. Às vezes é como morar no filme Brasil. :)

(Como tudo o mais) depende do seu aplicativo. Para algumas aplicações (geralmente as que nunca mudam ou as regras são melhores em constantes da vida real, ou seja, não muda visivelmente em eras, por exemplo, propriedades físicas e fórmulas), não faz sentido usar um mecanismo de regra, apenas Introduz complexidade adicional e exige que o desenvolvedor tenha um conjunto de habilidades maior.

Para outras aplicações, é realmente uma boa ideia. Tomemos, por exemplo, processamento de pedidos (pedidos de qualquer coisa, desde o faturamento até o processamento de transações de moeda), de vez em quando há uma alteração minuciosa em alguma lei ou código relevante (no sentido judicial) que exige que você atenda a um novo requisito (por exemplo, imposto sobre vendas de vendas , um clássico). Em vez de tentar forçar sua antiga aplicação nessa nova situação em que, de repente, você deve pensar sobre o imposto sobre vendas, onde, como antes, é mais fácil adaptar seu conjunto de regras, em vez de ter que se intrometer em potencialmente um grande conjunto do seu código.

Em seguida, a próxima emenda do governo local exige relatórios de todas as vendas dentro de um determinado critério, em vez de você ter que entrar e acrescentar isso também. No final, você acabará com um código muito complexo que será bastante difícil de gerenciar quando você se virar e deseja reverter o efeito de uma das regras, sem influenciar todos os outros ...

Todo mundo até agora tem sido muito positivo sobre os motores de regras, mas aconselho o leitor a ser cauteloso. Quando um problema se torna um pouco mais complicado, você pode de repente descobrir que um mecanismo de regras inteiro foi inadequado ou muito mais complicado do que em um idioma mais poderoso. Além disso, para muitos problemas, os motores de regras não serão capazes de detectar facilmente propriedades que reduzem bastante o tempo de execução e a pegada de memória de avaliar a condição. Existem relativamente poucas situações em que eu preferiria um mecanismo de regra a uma estrutura de injeção de dependência ou uma linguagem de programação mais dinâmica.

"Mas realmente, quantos aplicativos realmente têm tantas mudanças?"

Honestamente, todo aplicativo em que trabalhei passou por um fluxo de trabalho sério e/ou alterações lógicas do conceito até bem após a implantação. É o motivo número um para a programação de "manutenção" ...

A realidade é que você não consegue pensar em tudo com antecedência, daí a razão dos processos ágeis. Além disso, o BA sempre parece perder algo vital até que seja encontrado nos testes.

Os motores de regra o forçam a separar verdadeiramente a lógica de negócios da apresentação e armazenamento. Além disso, se estiver usando o motor certo, seus BAs podem adicionar e remover a lógica conforme necessário. Como Chris Marasti-Georg disse, coloca o ônus no BA. Mas mais do que isso, permite que o BA obtenha exatamente o que eles estão pedindo.

Um mecanismo de regras é uma vitória em um aplicativo configurável, onde você não deseja fazer compilações personalizadas, se puder ser evitado. Eles também são bons em centralizar grandes bases de regras e algoritmos como Rete são eficientes para corresponder rapidamente a grandes conjuntos de regras.

Muitas respostas boas já, mas queria adicionar algumas coisas:

  1. Ao automatizar uma decisão de qualquer complexidade, a coisa crítica se torna rapidamente sua capacidade de gerenciar, em vez de executar a lógica envolvida. Um mecanismo de regras não ajudará com isso - você precisa pensar nos recursos de gerenciamento de regras que um sistema de gerenciamento de regras de negócios possui. A maioria dos motores de regras de código aberto e de código aberto evoluiu para sistemas de gerenciamento de regras com repositórios, relatando o uso de regras, versão etc. Um repositório de regras, estruturado em conjuntos de regras coerentes que podem ser orquestrados para tomar decisões de negócios é muito mais fácil de gerenciar do que qualquer um milhares de linhas de código ou sopa de regras.
  2. Existem muitas maneiras de usar uma abordagem declarativa baseada em regras. O uso de regras para gerenciar uma interface do usuário ou como parte da definição de um processo pode ser muito eficaz. O uso mais valioso de uma abordagem de regras, no entanto, é automatizar as decisões de negócios e entregá -lo como serviços de decisão pouco acoplados que recebem informações, executam regras e retornam uma resposta - uma decisão. A coisa destes como serviços que respondem a outros serviços como "Este cliente é um bom risco de crédito" ou "que desconto devo dar a este cliente para este pedido ou" qual é o melhor cruzamento para esse cliente no momento. Esses serviços de decisão podem ser construídos com muita eficácia usando um sistema de gerenciamento de regras e permitir uma fácil integração de análises ao longo do tempo, algo que muitos decisões se beneficiam.

Eu vejo mecanismos de regra, processo e dados (também conhecido como bancos de dados) como essencialmente semelhantes. Mas, por algum motivo, nunca dizemos que o BlackBoxing the Persistence Subsistema é ruim.

Em segundo lugar, do meu POV, um modelo anêmico não é leve que é leve em implementação de comportamentos, é aquele que é leve em comportamentos em si. O método real que descreve um comportamento disponível em um objeto de modelo de domínio não precisa ser feito pelo próprio objeto.

A maior complexidade da minha experiência em Rule Engines é que:

  1. do OOP POV, é muito difícil refatorar e testar regras escritas em uma linguagem declarativa enquanto você refatora o código que as afeta.
  2. Freqüentemente, devemos sempre pensar na ordem de execução das regras, que se torna uma bagunça quando há muitas delas.
  3. Algumas pequenas alterações podem desencadear comportamento incorreto das regras, levando a bugs de produção.Na prática nem sempre é possível cobrir todos os casos com testes antecipados.
  4. As regras que modificam objetos usados ​​em outros também aumentam a complexidade, fazendo com que os desenvolvedores os dividam em estágios.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top