当前位置:   article > 正文

drools 6.5 -DSL 领域特殊语言_drools规则引擎和dsl的关系

drools规则引擎和dsl的关系

本文目录结构
- 1.规则引擎面临的问题
- 2. DSL领域特殊语言
- 3. DSl 好处
- 4. DSl 实现
- 5. DSL -小例子
- 6 附 转换后规则


1. 规则引擎面临的问题:

业务规则的实现大部分是由开发人员来实现的
业务规则需要业务分析人员能够阅读和理解
业务规则的可读性和用户的友好性都不太好

2. DSL领域特殊语言

DSL == Domain Specific Language
以贴近业务领域的方式,即以类自然语言的方式来构造软件,使得我们不用花费太多精力就能看懂代码所对应的业务含义
它是创建规则语言的一种方式,致力于解决我们的问题域
DSL相当于一个转换器,它能将某一领域内的术语转换成规则语言

3. DSl 好处

领域专家只需要业务,而不需要关注技术
规则模式可以被重复利用
使业务领域专家更平滑的将业务领域中的概念转换成DSL(存放于dslr文件中)
提高业务规则的可读性

4. DSl 实现

4.1 DSL包含两种类型的文件

dslr 文件:存放了一些业务领域专用语言
dsl文件:定义了领域专用语言到规则语言的映射,能将领域专用语言转换成规则语言

4.2 转换过程

dslr文件通过dsl转换之后的结果是一个符合语法的DRL文件(自然语言到规则语言的转换)

这里写图片描述


5. DSL -小例子

用户买电影票小例子。
Silver卡用户, 买票获得10元代金劵;
Gold卡用户, 买票获得30元代金劵;
Platinum卡用户, 买票获得50元代金劵;

5.1POJO

有两个 pojo 对象 一个是用户,一个是电影票

Customer

package com.us.ticketDSL;

/**
 * Created by yangyibo on 16/12/21.
 */
public class Customer {
    private String name;
    private String subscription;

    public Customer() {

    }

    public Customer(final String name,

                    final String subscription) {
        super();
        this.name = name;
        this.subscription = subscription;
    }

    public String getName() {
        return this.name;
    }

    public String getSubscription() {
        return this.subscription;
    }


    public String toString() {
        return "[Customer " + this.name + " : " + this.subscription + "]";
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
Ticket
package com.us.ticketDSL;

/**
 * Created by yangyibo on 16/12/21.
 */
public class Ticket {
    private Customer customer;
    private String   status;

    public Ticket() {

    }

    public Ticket(final Customer customer) {
        super();
        this.customer = customer;
        this.status = "买票";
    }

    public String getStatus() {
        return this.status;
    }

    public void setStatus(final String status) {
        this.status = status;
    }

    public Customer getCustomer() {
        return this.customer;
    }

    public String toString() {
        return "[好看电影院: 尊敬的"+this.customer.getSubscription()+" 卡用户 " + this.customer.getName() + ",您" + this.status + "]";
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

5.2 kmodule.xml

如果没有 kmodule.xml 文件,在META-INF 文件夹下新建kmodule.xml 文件填写如下内容。

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
  <!--DSL买票-->
    <kbase name="TicketWithDSLKB" packages="com.us.ticketDSL">
        <ksession name="TicketWithDSLKS"/>
    </kbase>
    </kmodule>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5.3 DSL 文件

注意:DSL文件和DSLR 文件之间的关系是条件对应替换,例如我DSRL 文件中的“ 我要买张票 "买票"“ 通过DSR 文件转换,转换后为“ customer : Customer( )   ticket : Ticket( customer == customer, status == "{status}" )“ 
本文的DSL和DSLR文件替换后如文章末尾“6 附 转换后规则 “展示所示。
  • 1
  • 2

ticket.dsl文件内容

[condition][]我要买张票 "{status}"=customer : Customer( )   ticket : Ticket( customer == customer, status == "{status}" )
[condition][]这是一个 "{subscription}" 卡客户 "{status}"=customer : Customer(subscription == "{subscription}") ticket : Ticket( customer == customer, status == "{status}")
[consequence][]打印 "{message}"=System.out.println(customer.getName()+"{message} ");
[consequence][]优惠=ticket.setStatus("获得了一张代金劵");update(ticket);
[consequence][]Send  email=sendEscalationEmail( customer, ticket );
  • 1
  • 2
  • 3
  • 4
  • 5

5.4 DSLR 文件

ticketing.dslr 文件内容

注意:duration 1000 属性是指此规则匹配成功后,另开线程1秒后执行,
  • 1
package com.us.ticketDSL
import com.us.ticketDSL.Customer;
import com.us.ticketDSL.Ticket;
expander ticketing.dsl

rule "New Ticket"
    salience 10
    when
       我要买张票 "买票"
    then
       打印 " 买到了一张票"
end

rule "Silver "

    duration 3000
    when
        这是一个 "Silver" 卡客户 "买票"

    then
        优惠
        打印 " 是个Silver卡用户, 买票获得10元代金劵。"
end

rule "Gold "
    duration 1000
    when
        这是一个 "Gold" 卡客户 "买票"
    then
        优惠
         打印 " 是个Gold卡用户, 买票获得30元代金劵。"
end

rule "Platinum "
    when
        这是一个 "Platinum" 卡客户 "买票"
    then
         优惠
         打印 " 是个Platinum卡用户, 买票获得50元代金劵。"
end


rule "Escalate"
    when
        我要买张票 "获得了一张代金劵"
    then
        Send  email
end


function void sendEscalationEmail( Customer customer, Ticket ticket ) {
    System.out.println( "Email : " + ticket );
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

5.5 测试

package com.us.ticketDSL;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
/**
 * Created by yangyibo on 16/12/21.
 */
public class TicketExampleWithDSL {
    public static void main(final String[] args) {
        KieContainer kc = KieServices.Factory.get().getKieClasspathContainer();
        execute( kc );
    }

    public static void execute( KieContainer kc ) {
        KieSession ksession = kc.newKieSession( "TicketWithDSLKS" );

        final Customer a = new Customer( "刘德华",
                "Gold" );
        final Customer b = new Customer( "郭富城",
                "Platinum" );
        final Customer c = new Customer( "张学友",
                "Silver" );
        final Customer d = new Customer( "黎明",
                "Silver" );

        final Ticket t1 = new Ticket( a );
        final Ticket t2 = new Ticket( b );
        final Ticket t3 = new Ticket( c );
        final Ticket t4 = new Ticket( d );

        ksession.insert( a );
        ksession.insert( b );
        ksession.insert( c );
        ksession.insert( d );

        ksession.insert( t1 );
        ksession.insert( t2 );
        ksession.insert( t3 );
        ksession.insert( t4 );

        ksession.fireAllRules();



        try {
            System.err.println( "[[ Sleeping 5 seconds ]]" );
            Thread.sleep( 5000 );
        } catch ( final InterruptedException e ) {
            e.printStackTrace();
        }

        System.err.println( "[[ awake ]]" );

        ksession.fireAllRules();

        ksession.dispose();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

输出:
刘德华 买到了一张票
郭富城 买到了一张票
张学友 买到了一张票
黎明 买到了一张票
郭富城 是个Platinum卡用户, 买票获得50元代金劵。
[[ Sleeping 5 seconds ]]
Email : [好看电影院: 尊敬的Platinum 卡用户 郭富城,您获得了一张代金劵]
[[ awake ]]
张学友 是个Silver卡用户, 买票获得10元代金劵。
黎明 是个Silver卡用户, 买票获得10元代金劵。
刘德华 是个Gold卡用户, 买票获得30元代金劵。
Email : [好看电影院: 尊敬的Silver 卡用户 张学友,您获得了一张代金劵]
Email : [好看电影院: 尊敬的Silver 卡用户 黎明,您获得了一张代金劵]
Email : [好看电影院: 尊敬的Gold 卡用户 刘德华,您获得了一张代金劵]



6 附 转换后规则,只为加深理解

实际上DSL 在执行是会在内部进行替换,按照本文DSL 和DSLR的替换结果应该如下:

注意:(此处代码只是用于理解DSL和DSLR 的替换,不用写在代码中)
  • 1
package com.us.ticketDSL
import com.us.ticketDSL.Customer;
import com.us.ticketDSL.Ticket;

function void sendEscalationEmail( Customer customer, Ticket ticket ) {
    System.out.println( "Email : " + ticket );
}

rule "New Ticket"
    salience 10
    when
        customer : Customer( )
        ticket : Ticket( customer == customer, status == "买票" )
    then
        System.out.println(customer.getName() + "买到了一张票" );
end

rule "Silver "
    duration 3000
    when
        customer : Customer( subscription == "Silver" )
        ticket : Ticket( customer == customer, status == "买票" )
    then
        ticket.setStatus("获得了一张代金劵");update(ticket);
         System.out.println(customer.getName() + "是个Silver卡用户, 买票获得10元代金劵。" );
end

rule "Gold "
    duration 1000
    when
        customer : Customer( subscription == "Gold" )
        ticket : Ticket( customer == customer, status == "买票" )
    then
       ticket.setStatus("获得了一张代金劵");update(ticket);
       System.out.println(customer.getName() + "是个Gold卡用户, 买票获得30元代金劵。" );

end

rule "Platinum "
    when
        customer : Customer( subscription == "Platinum" )
        ticket : Ticket( customer == customer, status == "买票" )
    then
       ticket.setStatus("获得了一张代金劵");update(ticket);
       System.out.println(customer.getName() + "是个Platinum卡用户, 买票获得50元代金劵。" );

end

rule "Escalate"
    when
        customer : Customer( )
        ticket : Ticket( customer == customer, status == "获得了一张代金劵" )
    then
        sendEscalationEmail( customer, ticket );
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/941681
推荐阅读
相关标签
  

闽ICP备14008679号