第二天:Drools的语法

来源:互联网 发布:装修设计图纸软件 编辑:程序博客网 时间:2024/05/18 01:50

大家好:

通过第一天的学习大家对于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 Stringname;

        public Room(String name) {

            // TODO Auto-generated constructor stub

            this.name = name;

        }

        // getter and setter methods here

        public String getName() {

            returnname;

        }

        public void setName(String name) {

            this.name = name;

        }

    }

 

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

    public static class Sprinkler {

        private Roomroom;

        private boolean on;

        public Sprinkler(Room room) {

            // TODO Auto-generated constructor stub

            this.room = room;

        }

        // getter and setter methods here

        public Room getRoom() {

            returnroom;

        }

        public void setRoom(Room room) {

            this.room = room;

        }

        public boolean isOn() {

            returnon;

        }

        public void setOn(boolean on) {

            this.on = on;

        }

    }

 

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

    public static class Fire {

        private Roomroom;

        // getter and setter methods here

        public Fire(Room room) {

            // TODO Auto-generated constructor stub

            this.room = room;

        }

        public Room getRoom() {

            returnroom;

        }

        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

0 0
原创粉丝点击