Rafael Benevides bio photo

Rafael Benevides

In a serious relationship with Software Development

Email Twitter Facebook Google+ LinkedIn Instagram Github Last.fm Youtube

Depois que postei sobre um recente trabalho utilizando o Drools surgiram bastante pessoas interessadas em utilizar o Drools em alguns projetos e também uma série de questionamentos do tipo: Em quais casos devo utilizar um engine de regras ? Como começar com o Drools ? E até: Tive "tal" problema. Qual a solução ?

Não conseguirei responder a todas as perguntas feitas em um só post, mas tenho procurado responder todas as perguntas feitas por e-mail ou pelo Google Talk. De maneira geral sempre quando alguém me pergunta se deve usar o Drools em seus projetos, respondo que não! Quase sempre é tão óbvio quando você precisa de um "processador de regras" em seus projetos, que se houver dúvidas, o seu caso/projeto não cabe a utilização. Outro fator para que eu sempre responda isto é que eu gosto dos princípios DRY e YAGNI.

Se você se deu conta de que você realmente precisa de um "processador de regras" então podemos passar para a resposta da segunda pergunta: Como começar com o Drools? O Drools trabalha básicamente com uma memória interna para processar as regras. Esta memória é chamada de "Working Memory" e nela pode ser colocado qualquer tipo de objeto Java.

Para ilustrar o seu funcionamento, usarei como exemplo uma empresa que pretende automatizar as residências de seus clientes fornecendo um serviço personalizado que permite ao cliente escolher suas próprias regras para ligar e desligar o ar-condicionado de acordo com a temperatura escolhida. Desta maneira, foram criadas 3 classes para o nosso domínio: Natureza (que possui uma temperatura), a classe ArCondicionado (para ser ligado e desligado e tem uma referência para a Casa na qual foi instalado) e a classe Casa (que possui obrigatoriamente um dono em um ar-condicionado).

Neste momento a empresa possui 3 clientes: Rafael, Frederico e João Gabriel. Os dois primeiros já informaram a empresa de automação quais são suas preferências - Rafael ( ar ligado entre 20 a 26 graus) e Frederico (ar ligado entre 18 e 21 graus). Isto deu origem as seguintes regras:

package benevides

rule "Ligar ar-condicionado do Rafael quando temperatura maior que 26 graus"
  when
    Casa( dono == "Rafael", $arCondicionado: arCondicionado)
    Natureza( temperatura > 26 )
  then
   $arCondicionado.ligar();
end

rule "Desligar ar-condicionado do Rafael quando temperatura menor que 20 graus"
  when        
    Casa( dono == "Rafael", $arCondicionado: arCondicionado  )
    Natureza( temperatura  < 20 )
  then
    $arCondicionado.desligar();
end

rule "Ligar ar-condicionado do Frederico quando temperatura maior que 21 graus"
  when
    Casa( dono == "Frederico", $arCondicionado: arCondicionado  )
    Natureza( temperatura  > 21 )
  then
    $arCondicionado.ligar();
end

rule "Desligar ar-condicionado do Frederico quando temperatura menor que 18 graus"
  when
    Casa( dono == "Frederico", $arCondicionado: arCondicionado  )
    Natureza( temperatura  < 18 )
  then         
    $arCondicionado.desligar();
end

Uma vez definida as regras, já podemos implementar uma classe que oscilará a temperatura decrescendo de 30 graus até 15 graus e depois retornando até 30 graus novamente. Para verificar o comportamento, vamos inserir na WorkingMemory do Drools as instâncias do objeto Casa (uma instância de cada cliente) e a cada alteração de temperatura, vamos atualizar a temperatura da instância da classe Natureza e também atualizar esta instância na WorkingMemory.

Um detalhe importante: Para se atualizar uma instância que já está dentro da WorkingMemory (como é o caso do objeto Natureza, é necessário possuir um "Handle" para este objeto.

Segue abaixo o método main que dispara as regras para cada alteração de temperatura:

O resultado é mostrado abaixo. Percebam que o cliente que não possui regras (João Gabriel) não foi mostrado no resultado por motivos óbvios.

Um erro muito comum e pensar no Drools como um mero substitudo para os IF's. Apesar da semelhança, o Drools não possui um "else". O pensamento correto é: "Dado um fato, qual a sua conseqüência?" Não estamos programando (fora do Java), estamos determinando regras!

Na próxima postagem pretendo falar um pouco mais sobre o método lerRegras() e seu uso dentro de servidores de aplicação.

Até breve!