De força ao Usuário com o Drools parte 3
Nos posts anteriores falei sobre o Drools e como ele poderia ser uma boa solução de BRMS. Agora vou mostrar outra forma de expor uma regra de negocio do seu sistema. A idéia agora é expor as regras com a linguagem do usuário. Isso possibilita que usuário com menor conhecimento de tecnologias consigam modificar o comportamento do sistema de uma maneira segura e eficiente.
Recomendo que você leia os dois posts anteriores para uma melhor compreensão deste post:
Utilizarei boa parte do código do exemplo anterior. A DSL pode ser internacionalizada para outros idiomas, isso seria útil se o seu sistema roda em diversos países e você tem pequenas variações nas regras de pais a pais.
Mas o que é um DSL?
Domain Specific Luanguage são linguagens para domínios bem específicos. Você pode estar pensando que nunca usou isso ou nunca vai usar, se esse for seu caso você não esta ligando o nome a pessoa. Exemplos de DSL são:
Por que usar um DSL?
Na prática você tem diversas vantagens. Se você passa um script ou uma tabela ou um ide para o usuário de negocio mexer ele tem que lidar com a tecnologia antes de lidar com o seu problema de verdade. Com a DSL esse impacto é bem mais reduzido, por que você escreve em português por exemplo e pode usar a linguagem local do usuário, usar as girias que o usuário usar, os jargões e os termos técnicos do usuário.
Você pode criar várias DSLs e cada uma delas para um setor da sua empresa ou várias DSLs para vários módulos. O complicado aqui não é fazer a DSL mas sim chegar em um acordo com os usuário em que syntax será utilizada. Isso tudo pode ocorrer na elicitação dos requisitos e durante a analise do sistema. Isso mesmo você não precisa do código pronto ou de todo o design do sistema para fazer isso. A grande vantagem aqui é que isso pode ser feito de forma paralela.
Criando a Sua DSL
Muito bem agora vamos a prática. Como disse antes vou utilizar o modelo anterior. Vou usar as mesmas regras que utilizei na Tabela de Decisão, só que agora expressadas em forma de DSRL. Esse é o formato de regras com DSL no Drools.
DSL em português chamada tarifas_DSL_pt_BR.dsl
Vocês podem ver que existe tuas tags principais aqui que são: [condition] e [consequence]. São auto-explicativas. Tudo que estiver antes do "=" é syntax e toda vez que você quiser colocar um parâmetro você faz "{nomeDoParametro}". Tudo que tem depois do "=" se refere ao mapeamento Java, ou seja que código Java você quer executar quando isso for válido.
Neste caso na condição estou procurando na memória de trabalho do Drools por um objeto Carro que tenha cor igual a do parâmetro e tenha o modelo igual o do parâmetro. Na conseqüência estou aplicando a tarifação e realizando o aluguel pelo valor do parâmetro do aluguel.
Então agora vamos ao uso dessa DSL em um artefato de regras do Drools. tarifas.dslr
Aqui estou importando os objetos necessário a DSL e estou dizendo que vou usar essa dsl através da palavra reservada expander. Além disso defini várias regras, no caso essas eram as mesmas 3 primeiras regras que existem na tabela de decisão do post anterior.
Ok. Agora na hora de montar a base de conhecimentos precisamos adicionar esses dois recursos para isso iremos utilizar um código como o que segue a baixo.
Se você quiser pode conferir os fontes completos no meu SVN do Beanstalk aqui. São os mesmos fontes da parte dois dessa série de artigos. Porem modifiquei os mesmos para suportarem a utilização de DSL.
Até a Próxima, Abraços.
Recomendo que você leia os dois posts anteriores para uma melhor compreensão deste post:
Utilizarei boa parte do código do exemplo anterior. A DSL pode ser internacionalizada para outros idiomas, isso seria útil se o seu sistema roda em diversos países e você tem pequenas variações nas regras de pais a pais.
Mas o que é um DSL?
Domain Specific Luanguage são linguagens para domínios bem específicos. Você pode estar pensando que nunca usou isso ou nunca vai usar, se esse for seu caso você não esta ligando o nome a pessoa. Exemplos de DSL são:
- MS DOS
- SQL
- Bash no Linux
Por que usar um DSL?
Na prática você tem diversas vantagens. Se você passa um script ou uma tabela ou um ide para o usuário de negocio mexer ele tem que lidar com a tecnologia antes de lidar com o seu problema de verdade. Com a DSL esse impacto é bem mais reduzido, por que você escreve em português por exemplo e pode usar a linguagem local do usuário, usar as girias que o usuário usar, os jargões e os termos técnicos do usuário.
Você pode criar várias DSLs e cada uma delas para um setor da sua empresa ou várias DSLs para vários módulos. O complicado aqui não é fazer a DSL mas sim chegar em um acordo com os usuário em que syntax será utilizada. Isso tudo pode ocorrer na elicitação dos requisitos e durante a analise do sistema. Isso mesmo você não precisa do código pronto ou de todo o design do sistema para fazer isso. A grande vantagem aqui é que isso pode ser feito de forma paralela.
Criando a Sua DSL
Muito bem agora vamos a prática. Como disse antes vou utilizar o modelo anterior. Vou usar as mesmas regras que utilizei na Tabela de Decisão, só que agora expressadas em forma de DSRL. Esse é o formato de regras com DSL no Drools.
DSL em português chamada tarifas_DSL_pt_BR.dsl
[condition][]Se o carro eh um {modeloCarro} e sua cor eh {corCarro}=c: Carro( modelo == {modeloCarro}, cor == {corCarro} ) [consequence][]Tarifa de locação eh {tarifaLoc} reais=new ServiceFacadesLocator().getLocarCarroService().locar(c,null,new ValorLocacao({tarifaLoc}));
Vocês podem ver que existe tuas tags principais aqui que são: [condition] e [consequence]. São auto-explicativas. Tudo que estiver antes do "=" é syntax e toda vez que você quiser colocar um parâmetro você faz "{nomeDoParametro}". Tudo que tem depois do "=" se refere ao mapeamento Java, ou seja que código Java você quer executar quando isso for válido.
Neste caso na condição estou procurando na memória de trabalho do Drools por um objeto Carro que tenha cor igual a do parâmetro e tenha o modelo igual o do parâmetro. Na conseqüência estou aplicando a tarifação e realizando o aluguel pelo valor do parâmetro do aluguel.
Então agora vamos ao uso dessa DSL em um artefato de regras do Drools. tarifas.dslr
# # Regras de tarifação da locação de carros. # # @autor Diego Pacheco # @Since 25/03/2009 # @version 1.0 # package com.blogspot.diegopacheco.drools.rules import com.blogspot.diegopacheco.drools.model.* import com.blogspot.diegopacheco.drools.model.service.* expander tarifas_DSL_pt_BR.dsl rule "Carro Bararo 1" when Se o carro eh um "Gol" e sua cor eh "branco" then Tarifa de locação eh 250 reais end rule "Carro Bararo 2" when Se o carro eh um "Gol" e sua cor eh "bordo" then Tarifa de locação eh 280 reais end rule "Carro Medio 1" when Se o carro eh um "Fox" e sua cor eh "vermelho" then Tarifa de locação eh 300 reais end
Aqui estou importando os objetos necessário a DSL e estou dizendo que vou usar essa dsl através da palavra reservada expander. Além disso defini várias regras, no caso essas eram as mesmas 3 primeiras regras que existem na tabela de decisão do post anterior.
Ok. Agora na hora de montar a base de conhecimentos precisamos adicionar esses dois recursos para isso iremos utilizar um código como o que segue a baixo.
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); // Adiciona a DSL criada e a regra que usa a DSL kbuilder.add(ResourceFactory.newClassPathResource("tarifas_DSL_pt_BR.dsl"), ResourceType.DSL); kbuilder.add(ResourceFactory.newClassPathResource("tarifas.dslr"), ResourceType.DSLR);
Se você quiser pode conferir os fontes completos no meu SVN do Beanstalk aqui. São os mesmos fontes da parte dois dessa série de artigos. Porem modifiquei os mesmos para suportarem a utilização de DSL.
Até a Próxima, Abraços.