27.12.05

Utilizando Drools II. Caso práctico 2/2

Como ya hemos visto, Drools es un motor de reglas de negocio. ¿Cuándo podemos utilizar Drools?. Pues,por ejemplo:



  • Cuando la lógica de negocio sea compleja pero se pueda expresar mediante cláusulas IF-THEN.

  • Cuando vaya a haber muhcos cambios.

  • Cuando el cliente no tiene clara su lógica de negocio.

  • Cuando el cliente se exprese de manera natural mediante IF-THEN.


Básicamente, al utilizar Drools tendremos que escribir dos elementos: las reglas de negocio y el sistema que utilizará dichas reglas (a a través de Drools). Drools permite escribir reglas en lenguaje Java, Python o Groovy. En este ejemplo vamos a escribir las reglas utilizando Java. Las reglas se almacenan en un archivo DRL, que no es más que un archivo XML con la definición de las reglas. La estructura (simplificada) de un archivo DRL se muestra a continuación



  • Imports de elementos de paquetes.

  • Declaración de funciones auxiliares.

  • Nombre del conjunto de reglas.

  • Reglas


Para cada regla podemos indicar:



  • Nombre de la regla.

  • Parámetros (los nombres son importantes).

  • Conciones para que la regla se dispare.

  • Consecuencias.


A continuación se muestra un ejemplo de un archivo DRL completo para el ejemplo que expusimos en el post aterior. Concretamente este archivo DRL incluye una regla por la que, si el precido de un pedido es superior a 100, le descuenta el 5%.


<?xml version="1.0"?>
<rule-set name="BusinessRulesSample"
xmlns="http://drools.org/rules"
xmlns:java="http://drools.org/semantics/java"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/rules rules.xsd
http://drools.org/semantics/java java.xsd">

<java:import> java.lang.Object </java:import>
<java:import> java.lang.String </java:import>
<java:import> ebr.beans.Pedido </java:import>

 <rule name="Calculo del total del pedido">
<parameter identifier="pedido">
<class>ebr.beans.Pedido</class>
<java:condition>
pedido.getCalculoTotalOriginal() >= 100.0
</java:condition>
<java:consequence>
pedido.setTotalFinal(pedido.getCalculoTotalOriginal() * 0.95);
</java:consequence>
</rule>

Para disparar esta regla vamos a escribir, en prime lugar, los beans que van a guardar la información
del workspace y un sencillo programa que utilice el motor. Uno de los beans guardará información sobre cada producto (nombre cantidad y precio) y el otro guardará la lista de productos. El sgeundo bean se muestra a continuación.

import java.util.*;

public class Pedido {

 private List entradas;
private double totalFinal;

 public Pedido() {
entradas = new ArrayList();
this.totalFinal = -1.0;
}

 public void addEntrada (Entrada e) {
this.entradas.add(e);
}

public List getEntradas() {
return this.entradas;
}

public void getEntradas(List entradas) {
this.entradas = entradas;
}

public double getCalculoTotalOriginal() {
Entrada e;
double total = .0;
Iterator it = this.entradas.iterator();

while(it.hasNext()) {
e = (Entrada) it.next();
total += e.getCantidad();
}

return total;
}

public void setTotalFinal(double total) {
this.totalFinal = total;
}

Para trabajar con Drools necesitamos importar los sigientes elementos:


  import java.io.IOException;
import org.drools.DroolsException;
import org.drools.RuleBase;
import org.drools.WorkingMemory;
import org.drools.event.DebugWorkingMemoryEventListener;
import org.drools.io.RuleBaseLoader;
import org.xml.sax.SAXException;

Lo primero que tenemos que hacer es crear un nuevo pedido:


  Entrada e1 = new Entrada("A", 10, 5);
Entrada e2 = new Entrada("B", 6, 6);
Pedido pedido = new Pedido();
pedido.addEntrada (e1);

En este pedido tenemos 10 unidades del producto A cada una a un precio de 5 y 6 unidades del B a un
precio de 6. A continuación creamos nuestro motor de reglas para que procese el archivo de reglas visto más arriba:
  BREngine br = new BREngine();
RuleBase businessRules = RuleBaseLoader.loadFromUrl(
BREngine.class.getResource( "rules01.drl" ) );

Limpiamos el espacio de trabajo e instalamos un listener que será avisado cada vez que Drools ejecute una regla. Este listener mostrará un mnesaje por la salida estándar.
  WorkingMemory workingMemory = businessRules.newWorkingMemory();
workingMemory.addEventListener(new DebugWorkingMemoryEventListener());

A continuación añadimos el pedido:


 workingMemory.assertObject(fact);

Y a trabajar:


 workingMemory.fireAllRules();

Nota, los try / catch de todas las pisbles excepciones han sido omitios.

19.12.05

Cumplimos un año. Gracias !!!!!!

Saludos a todos.

Recientemente este blog ha cumplido un año. Sinceramente, cuando empecé no esperaba que fuera capaz de mantenerlo todo este tiempo, no por falta d einetrés sino de tiempo.

Os agradezco de todo corazón vuestro tiempo a todos los que de vez en cuando venís por aquí. Lamento no poder actualizar esto con tanta frecuencia como me gustaría pero espero que, lo que ponga, os sea de utilidad.

Felices fiesta a todos.

(PD: sí, sí, está pendiente la continuación del post de Drools, a ver si llegan ya las vacaciones y tengo tiempo de ponerme con ello).