Artigo Java Magazine 15 - Programação com Regras

Conheça a programação baseada em regras, que permite implementar estruturas de decisões extremamente complexas com eficiência.

Uma das melhores e mais modernas linguagens de programação imperativa e orientada a objetos, Java suporta a maior parte do desenvolvimento de software atual. Mas existem muitas tarefas que se beneficiam de linguagens especializadas.

Por exemplo, para acessar bancos de dados (SGBDs) relacionais você normalmente usa SQL. Como sabemos, o SQL não é uma “linguagem primária” da plataforma Java: nenhum compilador ou interpretador de SQL faz parte da JVM. Além disso, código SQL não é compilado diretamente para bytecode (o que não faria muito sentido, pois a JVM não integra um SGBD). Ainda assim, o SQL é suportado de forma “secundária” através da API JDBC e seus drivers.

Outra aplicação de linguagens especializadas é na programação baseada em regras. Um exemplo é a linguagem Prolog, que muitos aprendem na universidade, em disciplinas de Lógica ou Inteligência Artificial (IA). Todas as técnicas de IA podem ser implementadas numa linguagem convencional, como Java, usando bibliotecas/APIs comuns, em que todas as tarefas são conduzidas através da criação de objetos e invocação de métodos da API. Mas em alguns casos isso seria parecido com alguns mecanismos de persistência que não suportam SQL. Eles resolvem problemas simples, mas você logo sente falta do SQL quando precisa de consultas complexas ou quer migrar para outro produto. Assim como no caso do SQL, a programação baseada em regras define um novo paradigma de programação, e exige linguagens próprias para maximizar a facilidade de desenvolvimento, o desempenho ou a interoperabilidade.

Existem implementações de linguagens de IA tradicionais para máquinas virtuais Java. Só de Prolog contei 14 – incluindo interpretadores escritos em Java e compiladores que geram bytecode. Produtos desse tipo são interessantes para quem já está habituado às outras linguagens, ou precisa lidar com código legado, mas em geral haverá redundância de funcionalidades e dificuldades quanto à portabilidade.

A JSR-94 e engines de regras

Uma solução para esses problemas veio com a JSR-94 (Java Rule Engine API). A JSR-94 padroniza a API de um engine de regras, como é chamado o coração de um sistema de processamento de regras (você também encontrará a expressão mais pomposa “motor de inferência”, significando a mesma coisa).

Muitos engines de regras, tanto proprietários quanto livres, foram implementados para a plataforma Java, antes de qualquer padronização. A JSR-94 foi aprovada apenas no final de 2003, e os produtos ainda estão correndo atrás da compatibilidade. Para este artigo escolhi o JESS, que é a implementação de referência (RI) da JSR-94.

Um engine de regras trabalha com dois conceitos principais. O primeiro é a base de conhecimento, organizada como um conjunto de fatos (afirmações que conhecemos ser verdadeiras, como “Hoje faz sol” ou “nome = ‘Osvaldo’”). O segundo conceito é um conjunto de regras (ruleset) com uma estrutura "se-então", por exempl "se hoje está fazendo sol, então vou à praia”. O funcionamento do engine consiste em cruzar as regras com os fatos aos quais se aplicam, gerando novos fatos, ou ações arbitrárias.

Cada engine pode suportar linguagens diferentes para a especificação das regras e da base de conhecimento. Voltando à comparação, é como se a API JDBC não exigisse que todos os bancos de dados suportassem SQL: todos os drivers teriam que implementar métodos como executeQuery(consulta), mas a linguagem usada no parâmetro iria variar de um SGBD para outro. Se você pensar bem, é isso o que acontece. Apesar da existência dos padrões ANSI, não há dois bancos de dados que implementem exatamente o mesmo SQL, sendo possível utilizar, mesmo via JDBC, um enorme número de sintaxes proprietárias. A JSR-94 é um pouco parecida com isso. Ainda que cada engine possa usar uma linguagem diferente, essas linguagens têm o mesmo propósito e a mesma funcionalidade básica – muitas diferenças não passam de detalhes sintáticos.

A utilidade de regras

Em primeiro lugar, vamos à pergunta essencial: “para que serve isto?”. O estilo imperativo de programação é muito bom quando temos algoritmos relativamente simples na tomada de decisões: "se o saldo é negativo, debite os juros"; "se o botão Ok foi pressionado, grave as alterações" etc.

Um sistema de informação típico pode ser visto como uma grande coleção de regras do tipo “se isto for verdade, então faça aquilo”. Decisões mais complexas costumam resultar em métodos cheios de estruturas de controle, variáveis temporárias, e invocações a outros métodos, nos quais são encapsuladas as decisões comuns ou recorrentes. Mas, ainda nos piores casos, a complexidade dessas decisões é relativamente pequena, podendo ser representada de forma simples, seja numa linguagem de programação como Java, seja numa linguagem de modelagem como UML (por exemplo, em diagramas de seqüência/colaboração e de estados).

O problema é quando o processo de decisão atinge um nível de complexidade muito grande. Tomemos como exemplo um programa que simula o trabalho de um clínico geral, tentando diagnosticar doenças a partir dos sintomas de um paciente. A princípio, poderíamos fazer o serviço em Java:


if (temperatura >= 37.5 
  && dorRenal
  && exame.possuiBacteriasGramPositivas() ) 
return PIELONEFRITE; 

Mas logo iremos perceber complicações:

A solução é ter uma linguagem de descrição de regras que responda a esses requisitos, e um ambiente de execução (o engine) que entenda esta linguagem e “execute” as regras cruzando-as com a base de conhecimento.

Neste artigo, vamos adotar como ambiente de execução o JESS 6.1, e como linguagem de regras o CLIPS. Resumidamente, CLIPS é uma linguagem especializada na construção de sistemas baseados em regras, e o JESS é apenas um dos engines de regras implementados 100% em Java, o que torna seu uso muito conveniente para nós. Mesmo sendo um engine dedicado à integração com aplicações Java, o JESS utiliza scripts em CLIPS para definir as regras, de forma que você precisará de alguma familiaridade com a sintaxe dessa linguagem (que iremos explicando ao longo do artigo). Veja mais sobre o engine e a linguagem no quadro “CLIPS, JESS, outros engines e a JSR-94”.."

[...] continue lendo...
Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados