简体   繁体   中英

How to refactor the following drools rule criteria into a function?

rule "size must be greater than 1 billion"
    when
        $typeMaster : TypeMaster ( $type : keyValue["type"] , 
                                   $code : keyValue["code"],
                                       ( $type in ( "CB1", "CB2" ) && $code == "123" ) ||
                                       ( $type in ( "B1", "B2" ) && $code == "234" ) &&
                                   keyValue["size"] <= 1000000000 )
    then
        messageService.save(Type.ERROR, kcontext, $typeMaster);
end

I have the aforementioned rule in drools that says in TypeMaster fact/object, there is a keyValue map, get the type and code and check their values against few criteria and when they are satisfied, check if size <= billion. if it satisfies the criteria, then, it will save the desired object with error and rule name in the consequence.

I would like to refactor the code. However I want all the type and code checks to be in the rules file because if any rule changes, it can be changed in the file itself rather than going into the Java code and change the hard-coded variables. Could you suggest?

How about adding the check methods to your TypeMaster Fact. Something like this

class TypeMaster {
  boolean isTypeIn( String... params ) {
    // Check if this.type is in params
  }
  boolean isCodeIn( String... params ) {
    // Check if this.code is in params
  }
  boolean isSizeSmallerOrEqualTo( long value ) {
    return this.size <= value  // You might not need this util method
  }
}

Then in your rule you'd have something like this

rule "size must be greater than 1 billion"
    when
        $typeMaster : TypeMaster ( typeIn( "CB1", "CB2" ) && codeIn( "123" ) ||
                                   typeIn( "B1", "B2" ) && codeIn( "234" ) &&
                                   sizeSmallerOrEqualTo( 1000000000  )
    then
        messageService.save(Type.ERROR, kcontext, $typeMaster);
end

I cannot verify right now whether the var args params work when calling the methods from Drools, but if it fails on that you can use arrays, multiple params etc

Another option would be to override getType() and getCode() in TypeMaster in such way that it'll directly return the values instead of getting them via map. Like this

class TypeMaster {
  Map values // this represents your key-value map
  getType() {
    return values.get( "type" )
  }
  getCode() {
    return values.get( "code" )
  }
  // getSize() similarly
}

After this your rule won't change much

rule "size must be greater than 1 billion"
    when
        $typeMaster : TypeMaster ( ( $type in ( "CB1", "CB2" ) && $code == "123" ) ||
                                   ( $type in ( "B1", "B2" ) && $code == "234" ) &&
                                     size <= 1000000000 )
    then
        messageService.save(Type.ERROR, kcontext, $typeMaster);
end

Hope you'll get the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM