第二天:Drools的语法

本文介绍了Drools规则引擎的基础知识,详细解释了规则的构成要素,包括属性、条件和结果部分。并通过实例展示了如何使用Drools解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好:

通过第一天的学习大家对于Drools的安装已经有一个初步的了解,接下来我们将进一步对drools的算法进行学习。

rule "name"

attributes

 when

LHS

Then

RHS

End

从代码 中可以看到,一个规则通常包括三个部分:属性部分(attribute)、条件部分(LHS)和结果部分(RHS)。对于一个完整的规则来说,这三个部分都是可选的。即:


也是完全正确的。

1.      条件部分

条件部分又被称之为Left Hand Side,简称为LHS,下文当中,如果没有特别指出,那么所说的LHS 均指规则的条件部分,在一个规则当中when 与then 中间的部分就是LHS 部分。在LHS 当中,可以包含0~n 个条件,如果LHS 部分没空的话,那么引擎会自动添加一个eval(true)的条件,由于该条件总是返回true,所以LHS 为空的规则总是返回true。LHS 部分是由一个或多个条件组成,条件又称之为pattern(匹配模式),多个pattern之间用可以使用and 或or 来进行连接,同时还可以使用小括号来确定pattern 的优先级。

一个pattern 的语法如下: [绑定变量名:]Object([field 约束]) 

对于一个pattern 来说“绑定变量名”是可选的,如果在当前规则的LHS 部分的其它的pattern 要用到这个对象,那么可以通过为该对象设定一个绑定变量名来实现对其引用,对于绑定变量的命名,通常的作法是为其添加一个“$”符号作为前缀,这样可以很好的与Fact的属性区别开来;绑定变量不仅可以用在对象上,也可以用在对象的属性上面,命名方法与对象的命名方法相同;“field 约束”是指当前对象里相关字段的条件限制,示例如下:


此段规则的定义如下:

规则名“check”

When部分为条件部分$i:InsurantInfo(age > 18 , gender == "female");

首先遍历InsurantInfo对象,找出所有InsurantInfo中符合条件年龄大于18,性别为female的。

之后判断$p:PolicyInfo(insurantInfo == $i);

遍历PolicyInfo找出所有PolicyInfo中有和这个对象一致的对象,如果有就将PolicyInfo信息输出。

2.      约束连接

对于对象内部的多个约束的连接,可以采用“&&”(and)、“||”(or)和“,”(and)来实现,代码清单中规则的LHS 部分的两个pattern 就里对象内部约束就采用“,”来实现,“&&”(and)、“||”(or)和“,”这三个连接符号如果没有用小括号来显示的定义优先级的话,那么它们的执行顺序是:“&&”(and)、“||”(or)和“,” “&&”优先级最高,表面上看“,”与“&&”具有相同的含义,但是有一点需要注意,“,”与“&&”和“||”不能混合使用,也就是说在有“&&”或“||”出现的LHS 当中,是不可以有“,”连接符出 现的,反之亦然。

3.      比较操作符

在Drools5当中共提供了十二种类型的比较操作符,分别

是:>、>=、<、<=、= =、!=、contains、not contains、memberof、not memberof、matches、not matches;在这十二种类型的比较操作符当中,前六个是比较常见也是用的比较多的比较操作符,着重对后六种类型的比较操作符进行介绍。

如下例所示:

判断insurantInfos中是否包含有一个符合条件的insurantInfo。


Drools不人性化部分,对象都需要插入到Ksession中。


4.      案例分析

在最后我们列出一个具体的事例来说明drools语言,通过这个例子我们可以看到在不同场景下规则执行的情况。

案例背景:火警报警系统。

当没有发生火警的时候,会报告一切ok。

当出现火警的时候,会自动打开消火栓进行灭火。

当火情消灭的时候,会关闭消火栓。

 

模型:

//房屋。参数:房屋名称

    public static class Room {

        private String name;

        public Room(String name) {

            // TODO Auto-generated constructor stub

            this.name = name;

        }

        // getter and setter methods here

        public String getName() {

            return name;

        }

        public void setName(String name) {

            this.name = name;

        }

    }

 

//消防灭火器。参数:对象房屋、警报是否打开

    public static class Sprinkler {

        private Room room;

        private boolean on;

        public Sprinkler(Room room) {

            // TODO Auto-generated constructor stub

            this.room = room;

        }

        // getter and setter methods here

        public Room getRoom() {

            return room;

        }

        public void setRoom(Room room) {

            this.room = room;

        }

        public boolean isOn() {

            return on;

        }

        public void setOn(boolean on) {

            this.on = on;

        }

    }

 

//火情。参数:对象房屋

    public static class Fire {

        private Room room;

        // getter and setter methods here

        public Fire(Room room) {

            // TODO Auto-generated constructor stub

            this.room = room;

        }

        public Room getRoom() {

            return room;

        }

        public void setRoom(Room room) {

            this.room = room;

        }

    }

 

    //警报

    public static class Alarm {}

 

规则:

 

rule "Raise the alarm when we haveone or more fires"

    when

        exists Fire();

    then

        System.out.println( "Raise the alarm");

        insert(new Alarm());

end

 

rule "When there is a fire turn onthe sprinkler"

    when

        Fire($room : room)

        $sprinkler : Sprinkler( room == $room,on == false )

    then

        System.out.println( "Turn on the sprinkler for room" +$room.getName() );

        modify( $sprinkler ) { setOn( true ) };

end

 

rule "Cancel the alarm when all thefires have gone"

    when

        not Fire();

        $alarm : Alarm();

    then

        System.out.println( "Cancel the alarm" );

        delete( $alarm );

end

 

rule "When the fire is gone turn offthe sprinkler"

    when

        $room : Room( )

        $sprinkler : Sprinkler( room == $room,on == true )

        not Fire( room == $room )

    then

        System.out.println( "Turn off the sprinkler forroom " + $room.getName());

        modify( $sprinkler ) { setOn( false ) };

end

 

rule "Status output when things areok"

    when

        not Alarm()

        not Sprinkler( on == true )

    then

        System.out.println( "Everything is ok" );

End

 

场景执行:

1.  一切OK

//初始化房屋和灭火器

        String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"};

        Map<String,Room> name2room = new HashMap<String,Room>();

        for( String name: names ){

            Roomroom = new Room(name);

            name2room.put( name, room );

            Ksession.insert( room );

            Sprinkler sprinkler = new Sprinkler(room);

            Ksession.insert( sprinkler );

        }

        Ksession.fireAllRules();

出现结果:Everything is ok

 

2.  出现火情

//出现火情

        Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );

        Fire officeFire = new Fire( name2room.get( "office" ) );

        FactHandle kitchenFireHandle =Ksession.insert( kitchenFire );

        FactHandle officeFireHandle =Ksession.insert( officeFire );

        Ksession.fireAllRules();

出现结果:

Raisethe alarm

Turnon the sprinkler for room kitchen

Turnon the sprinkler for room office

 

3.  扑灭火情:

//关闭火情

        Ksession.delete( kitchenFireHandle );

        Ksession.delete( officeFireHandle );

Ksession.fireAllRules();

出现结果:

Raisethe alarm

Turnon the sprinkler for room kitchen

Turnon the sprinkler for room office

Cancelthe alarm

Turnoff the sprinkler for room kitchen

Turnoff the sprinkler for room office

Everythingis ok

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值