Chapter 2-4-2 Introductory case of rule engine Drools - business rule management system - componentization - middle platform

3. Drools entry case

A full set of codes and materials are provided in full, click here to download

This section uses an introductory case of Drools to let everyone have a preliminary understanding of how to use Drools and have an overall concept of Drools.

3.1 Description of business scenarios

Business scenario: Consumers purchase books in the book mall, and after placing an order, they need to display the discounted price on the payment page. The specific preferential rules are as follows:

rule number rule name describe
1 rule one There is no discount for books purchased with a total price of less than 100 yuan
2 rule two A discount of 20 yuan for the total price of books purchased between 100 and 200 yuan
3 rule three A discount of 50 yuan for the total price of books purchased between 200 and 300 yuan
4 rule four A discount of 100 yuan for books purchased with a total price of 300 yuan or more

Now it is necessary to calculate the discounted price according to the above rules.

3.2 Development and implementation

Step 1: Create a maven project drools_quickstart and import drools-related maven coordinates

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.10.0.Final</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

Step 2: Create resources/META-INF/kmodule.xml configuration file according to drools requirements

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <!--
        name:specify kbase The name can be arbitrary, but it needs to be unique
        packages:Specifies the directory of the rule file, which needs to be filled in according to the actual situation, otherwise it cannot be loaded into the rule file
        default:Specify the current kbase Is it the default
    -->
    <kbase name="myKbase1" packages="rules" default="true">
        <!--
            name:specify ksession The name can be arbitrary, but it needs to be unique
            default:Specify the current session Is it the default
        -->
        <ksession name="ksession-rule" default="true"/>
    </kbase>
</kmodule>

Note: The name and location of the configuration file above are fixed and cannot be changed

Step 3: Create the entity class Order

package com.itheima.drools.entity;

/**
 * Order
 */
public class Order {
    private Double originalPrice;//The original price of the order, that is, the price before the discount
    private Double realPrice;//The real price of the order, that is, the price after the discount

    public String toString() {
        return "Order{" +
                "originalPrice=" + originalPrice +
                ", realPrice=" + realPrice +
                '}';
    }

    public Double getOriginalPrice() {
        return originalPrice;
    }

    public void setOriginalPrice(Double originalPrice) {
        this.originalPrice = originalPrice;
    }

    public Double getRealPrice() {
        return realPrice;
    }

    public void setRealPrice(Double realPrice) {
        this.realPrice = realPrice;
    }
}

Step 4: Create a rule file resources/rules/bookDiscount.drl

//Book Promotion Rules
package book.discount
import com.itheima.drools.entity.Order

//Rule 1: There is no discount for books purchased with a total price of less than 100 yuan
rule "book_discount_1"
    when
        $order:Order(originalPrice < 100)
    then
        $order.setRealPrice($order.getOriginalPrice());
        System.out.println("Successfully matched to rule 1: no discount for books purchased with a total price of less than 100 yuan");
end

//Rule 2: A discount of 20 yuan for the total price of books purchased between 100 and 200 yuan
rule "book_discount_2"
    when
        $order:Order(originalPrice < 200 && originalPrice >= 100)
    then
        $order.setRealPrice($order.getOriginalPrice() - 20);
        System.out.println("Successfully matched to rule 2: 20 yuan discount for books purchased with a total price of 100 to 200 yuan");
end

//Rule 3: A discount of 50 yuan for the total price of books purchased between 200 and 300 yuan
rule "book_discount_3"
    when
        $order:Order(originalPrice <= 300 && originalPrice >= 200)
    then
        $order.setRealPrice($order.getOriginalPrice() - 50);
        System.out.println("Successfully matched to rule 3: a discount of 50 yuan for the total price of books purchased between 200 and 300 yuan");
end

//Rule 4: A discount of 100 yuan for books purchased with a total price of more than 300 yuan
rule "book_discount_4"
    when
        $order:Order(originalPrice >= 300)
    then
        $order.setRealPrice($order.getOriginalPrice() - 100);
        System.out.println("Successfully matched to rule 4: 100 yuan discount for books purchased with a total price of more than 300 yuan");
end

Step 5: Write unit tests

@Test
public void test1(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //Session object, used to interact with the rule engine
    KieSession kieSession = kieClasspathContainer.newKieSession();

    //Construct the order object, set the original price, and the rule engine calculates the discounted price according to the preferential rules
    Order order = new Order();
    order.setOriginalPrice(210D);

    //Provide the data to the rule engine, and the rule engine will perform rule matching based on the provided data
    kieSession.insert(order);

    //Activate the rule engine and execute the rule if the rule matches successfully
    kieSession.fireAllRules();
    //close session
    kieSession.dispose();

    System.out.println("Original price before discount:" + order.getOriginalPrice() +
                       "´╝îPrice after discount:" + order.getRealPrice());
}

Through the above introductory case, we can find that the main job of using the drools rule engine is to write the rule file, and define the business rules related to the business in the rule file. For example, this case defines the book discount rule. After the rules are defined, it is necessary to call the API provided by drools to provide data to the rule engine for rule pattern matching. The rule engine will execute the matching rules and return the calculated results to us.

You may have doubts, that is, although we did not write the judgment logic of the rules in the code, we still wrote the business rules in the rule file. What is the essential difference between this and writing the rules in the code?

We have actually mentioned earlier that business rules can be managed dynamically when using a rule engine. Business personnel can manage business rules like managing data, such as querying, adding, updating, statistics, and submitting business rules. This makes it possible to adjust business rules without restarting the service.

3.3 Summary

3.3.1 Rule Engine Composition

The drools rule engine consists of the following three parts:

  • Working Memory
  • Rule Base (rule base)
  • Inference Engine

Among them, Inference Engine (reasoning engine) includes:

  • Pattern Matcher
  • Agenda
  • Execution Engine

As shown below:

3.3.2 Description of related concepts

Working Memory: working memory, the drools rule engine will obtain data from Working Memory and perform pattern matching with the rules defined in the rule file, so the application we develop only needs to insert our data into Working Memory, such as this In the case, we call kieSession.insert(order) to insert the order object into the working memory.

Fact: Fact means that in the application of drools rules, the object after inserting an ordinary JavaBean into the Working Memory is the Fact object. For example, the Order object in this case belongs to the Fact object. The Fact object is a bridge or channel for data interaction between our application and the rule engine.

Rule Base: rule base, the rules we define in the rule file will be loaded into the rule base.

Pattern Matcher: A matcher that matches all the rules in the Rule Base with the Fact objects in the Working Memory, and the matching rules will be activated and put into the Agenda.

Agenda: Agenda, which is used to store the rules activated after pattern matching by the matcher.

Execution Engine: The execution engine executes the rules activated in Agenda.

3.3.3 Rule Engine Execution Process

3.3.4 Introduction to KIE

The API s we often use when operating Drools and the relationship between them are as follows:

From the core API above, it can be found that most of the class names start with Kie. The full name of Kie is Knowledge Is Everything, which is the abbreviation of "knowledge is everything", and it is the general name of a series of Jboss projects. As shown in the figure below, the main modules of Kie include OptaPlanner, Drools, UberFire, and jBPM.

As can be seen from the above figure, Drools is a component of the entire KIE project, and Drools also includes a Drools-WB module, which is a visual rule editor.

A full set of codes and materials are provided in full, click here to download

Tags: Java drools

Posted by lmninfo on Wed, 23 Nov 2022 01:22:10 +0300