Introduction to Drools – Drools简介

最后修改: 2017年 5月 18日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Drools is a Business Rule Management System (BRMS) solution. It provides a rule engine which processes facts and produces output as a result of rules and facts processing. Centralization of business logic makes it possible to introduce changes fast and cheap.

Drools是一个业务规则管理系统(BRMS)解决方案。它提供了一个处理事实的规则引擎,并作为规则和事实处理的结果产生输出。业务逻辑的集中化使其有可能快速而廉价地引入变化。

It also bridges the gap between the Business and Technical teams by providing a facility for writing the rules in a format which is easy to understand.

它还通过提供以易于理解的格式编写规则的设施,弥合了业务和技术团队之间的差距。

2. Maven Dependencies

2.Maven的依赖性

To get started with Drools, we need to first add a couple of dependencies in our pom.xml:

要开始使用Drools,我们首先需要在我们的pom.xml中添加几个依赖项。

<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-ci</artifactId>
    <version>7.1.0.Beta1</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>7.1.0.Beta1</version>
</dependency>

The latest version of both dependencies is available on Maven Central Repository as kie-ci and drools-decisiontables.

这两个依赖项的最新版本在Maven中央仓库中以kie-cidrools-decisiontables的形式提供。

3. Drools Basics

3.Drools的基础知识

We are going to look at basic concepts of Drools:

我们要看一下Drools的基本概念。

  • Facts – represents data that serves as input for rules
  • Working Memory a storage with Facts, where they are used for pattern matching and can be modified, inserted and removed
  • Rule – represents a single rule which associates Facts with matching actions. It can be written in Drools Rule Language in the .drl files or as Decision Table in an excel spreadsheet
  • Knowledge Session – it holds all the resources required for firing rules; all Facts are inserted into session, and then matching rules are fired
  • Knowledge Base – represents the knowledge in the Drools ecosystem, it has the information about the resources where Rules are found, and also it creates the Knowledge Session
  • Module A module holds multiple Knowledge Bases which can hold different sessions

4. Java Configuration

4.Java配置

To fire rules on a given data, we need to instantiate the framework provided classes with information about the location of rule files and the Facts:

为了在给定的数据上启动规则,我们需要将框架提供的类实例化,其中包括规则文件的位置和Facts:的信息。

4.1. KieFileSystem

4.1.KieFileSystem

First, we need to set the KieFileSystem bean; this is an in-memory file system provided by the framework. Following code provides the container to define the Drools resources like rules files, decision tables, programmatically:

首先,我们需要设置KieFileSystembean;这是一个由框架提供的内存文件系统。下面的代码提供了一个容器,以编程方式定义Drools资源,如规则文件、决策表。

public KieFileSystem kieFileSystem() throws IOException {
    KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
        for (Resource file : getRuleFiles()) {
            kieFileSystem.write(
              ResourceFactory.newClassPathResource(
              RULES_PATH + file.getFilename(), "UTF-8"));
        }
        return kieFileSystem;
}

Here RULES_PATH denotes the location of rule files on the file system. Here we are reading the files from classpath which is typically /src/main/resources in case of a Maven project.

这里RULES_PATH表示文件系统中规则文件的位置。这里我们从classpath读取文件,如果是Maven项目,通常是/src/main/resources

4.2. KieContainer

4.2.KieContainer

Next, we need to set the KieContainer which is a placeholder for all the KieBases for particular KieModule. KieContainer is built with the help of other beans including KieFileSystem, KieModule, and KieBuilder.

接下来,我们需要设置KieContainer,它是特定KieModule的所有KieBases的一个占位符。KieContainer是在其他bean的帮助下建立的,包括KieFileSystem、KieModuleKieBuilder。

The buildAll() method invoked on KieBuilder builds all the resources and ties them to KieBase. It executes successfully only when it’s able to find and validate all of the rule files:

KieBuilder上调用的buildAll()方法构建了所有的资源,并将它们与KieBase绑定。只有当它能够找到并验证所有的规则文件时,它才会成功执行。

public KieContainer kieContainer() throws IOException {
    KieRepository kieRepository = getKieServices().getRepository();

    kieRepository.addKieModule(new KieModule() {
        public ReleaseId getReleaseId() {
            return kieRepository.getDefaultReleaseId();
        }
    });

    KieBuilder kieBuilder = getKieServices()
      .newKieBuilder(kieFileSystem())
      .buildAll();
    

    return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}

4.3. KieSession

4.3.KieSession

The rules are fired by opening a KieSession bean – which can be retrieved from KieContainer:

通过打开一个KieSessionbean来启动规则–它可以从KieContainer:中检索到。

public KieSession kieSession() throws IOException {
    return kieContainer().newKieSession();
}

5. Implementing Rules

5.实施规则

Now that we’re done with the setup, let’s have a look at a couple of options for creating rules.

现在我们已经完成了设置,让我们看一下创建规则的几个选项。

We’ll explore the rule implementation by an example of categorizing an applicant for a specific role, based on his current salary and number of years of experience he has.

我们将通过一个例子来探讨规则的实施,即根据一个申请人目前的工资和他所拥有的经验年限,对其进行分类,以获得特定的角色。

5.1. Drools Rule File (.drl)

5.1.Drools规则文件(.drl

Simply put, the Drools rule file contains all business rules.

简单地说,Drools规则文件包含所有的业务规则。

A rule includes a When-Then construct, here the When section lists the condition to be checked, and Then section lists the action to be taken if the condition is met:

一条规则包括一个When-Then 结构,这里的When部分列出了要检查的条件,Then部分列出了如果条件得到满足要采取的行动。

package com.baeldung.drools.rules;

import com.baeldung.drools.model.Applicant;

global com.baeldung.drools.model.SuggestedRole suggestedRole;

dialect  "mvel"

rule "Suggest Manager Role"
    when
        Applicant(experienceInYears > 10)
        Applicant(currentSalary > 1000000 && currentSalary <= 
         2500000)
    then
        suggestedRole.setRole("Manager");
end

This rule can be fired by inserting the Applicant and SuggestedRole facts in KieSession:

通过在KieSession:中插入ApplicantSuggestedRole事实,可以启动该规则。

public SuggestedRole suggestARoleForApplicant(
    Applicant applicant,SuggestedRole suggestedRole){
    KieSession kieSession = kieContainer.newKieSession();
    kieSession.insert(applicant);
    kieSession.setGlobal("suggestedRole",suggestedRole);
    kieSession.fireAllRules();
    // ...
}

It tests two conditions on Applicant instance and then based on the fulfillment of both conditions it sets the Role field in the SuggestedRole object.

它在Applicant实例上测试两个条件,然后根据这两个条件的满足情况,在SuggestedRole对象中设置Role字段。

This can be verified by executing the test:

这可以通过执行测试来验证。

@Test
public void whenCriteriaMatching_ThenSuggestManagerRole(){
    Applicant applicant = new Applicant("David", 37, 1600000.0,11);
    SuggestedRole suggestedRole = new SuggestedRole();
        
    applicantService.suggestARoleForApplicant(applicant, suggestedRole);
 
    assertEquals("Manager", suggestedRole.getRole());
}

In this example, we’ve used few Drools provided keywords. Let’s understand their use:

在这个例子中,我们使用了一些Drools提供的关键词。让我们了解一下它们的用途。

  • package – this is the package name we specify in the kmodule.xml, the rule file is located inside this package
  • import – this is similar to Java import statement, here we need to specify the classes which we are inserting in the KnowledgeSession
  • global – this is used to define a global level variable for a session; this can be used to pass input parameter or to get an output parameter to summarize the information for a session
  • dialect – a dialect specifies the syntax employed in the expressions in the condition section or action section. By default the dialect is Java. Drools also support dialect mvel; it is an expression language for Java-based applications. It supports the field and method/getter access
  • rule – this defines a rule block with a rule name
  • when – this specifies a rule condition, in this example the conditions which are checked are Applicant having experienceInYears more than ten years and currentSalary in a certain range
  • then – this block executes the action when the conditions in the when block met. In this example, the Applicant role is set as Manager

5.2. Decision Tables

5.2.决策表

A decision table provides the capability of defining rules in a pre-formatted Excel spreadsheet. The advantage with Drools provided Decision Table is that they are easy to understand even for a non-technical person.

决策表提供了在一个预先格式化的Excel电子表格中定义规则的能力。Drools提供的决策表的优势在于,即使是非技术人员,也很容易理解。

Also, it is useful when there are similar rules, but with different values, in this case, it is easier to add a new row on excel sheet in contrast to writing a new rule in .drl files. Let’s see what the structure of a decision table with an example of applying the label on a product based on the product type:

另外,当有类似的规则,但有不同的值时,它也很有用,在这种情况下,在excel表上添加新行比在.drl文件中写一个新规则更容易。让我们看看决策表的结构,以根据产品类型给产品贴标签为例。

Screen-Shot-2017-04-26-at-12.26.59-PM-2

The Decision Table is grouped in different sections the top one is like a header section where we specify the RuleSet (i.e. package where rule files are located), Import (Java classes to be imported) and Notes (comments about the purpose of rules).

决策表分为不同的部分,最上面的部分就像一个标题部分,我们指定RuleSet(即规则文件所在的包),Import(要导入的Java类)和Notes(关于规则目的的注释)。

The central section where we define rules is called RuleTable which groups the rules which are applied to the same domain object.

我们定义规则的中心部分被称为RuleTable,它将应用于同一领域对象的规则分组。

In the next row, we have column types CONDITION and ACTION. Within these columns, we can access the properties of the domain object mentioned in one row and their values in the subsequent rows.

在下一行,我们有列类型CONDITIONACTION。在这些列中,我们可以访问在一行中提到的域对象的属性,以及它们在后续行中的值。

The mechanism to fire the rules is similar to what we have seen with .drl files.

启动规则的机制与我们看到的.drl文件类似。

We can verify the outcome of applying these rules by executing the test:

我们可以通过执行测试来验证应用这些规则的结果。

@Test
public void whenProductTypeElectronic_ThenLabelBarcode() {
    Product product = new Product("Microwave", "Electronic");
    product = productService.applyLabelToProduct(product);
    
    assertEquals("BarCode", product.getLabel());
}

6. Conclusion

6.结论

In this quick article, we have explored making use of Drools as a business rule engine in our application. We’ve also seen the multiple ways by which we can write the rules in the Drools rule language as well as in easy to understand the language in spreadsheets.

在这篇文章中,我们已经探讨了在我们的应用程序中使用Drools作为业务规则引擎。我们也看到了多种方法,我们可以用Drools的规则语言以及容易理解的电子表格语言来编写规则。

As always, the complete code for this article is available over on GitHub.

与往常一样,本文的完整代码可在GitHub上获得over