java軽量級ルールエンジンeasy-rules使用紹介


軽量級ルールエンジンeasy-rules--参照
私達は業務コードを書いていますが、if/elseの山が多く必要です。コードの可読性が大幅に低下します。コードの中に大量の判断文が出ないようにする方法がありますか?答えはルールエンジンを使っていますが、伝統的なルールエンジンは重いです。例えば、オープンソースのDroolsは小さい需要の中では適用できません。最近ギthubの上で馬鹿なJavaのルールエンジンEasy-Riulesを見ました。ここで自分の書いたデモと一緒にこのルールエンジンをどう使うかを紹介します。皆さんの助けになりたいです。
easy-rulesの特徴
  • 軽量クラスと使いやすい
  • POJOの開発と注釈に基づくプログラミングモデル
  • MVEL表現に基づくプログラミングモデル(極めて簡単な規則に適用され、一般的には推奨されない)
  • は、簡単な規則に従って、組み合わせルールを作成することをサポートする
  • 便利であり、javaの抽象的なトラフィックモデル規則
  • に適用される。
    これは主にいくつかの主要なクラスまたはインターフェースを含みます。Rule、RulesEngine、Rule Listener、Factsにはいくつかの主要な注釈があります。@Act、@Condation、@Fact、@Priority、@Rule
    例1:POJO開発と注釈に基づくプログラミングモデル:判断1-50において、3または8によって割り出された数
    まずマvenはeasy-rulesを導入します。
    
       <dependency>
          <groupId>org.jeasy</groupId>
          <artifactId>easy-rules-core</artifactId>
          <version>3.3.0</version>
        </dependency>
        <dependency>
          <groupId>org.jeasy</groupId>
          <artifactId>easy-rules-mvel</artifactId>
          <version>3.3.0</version>
        </dependency>
    編纂規則POJO:
    ルール1
    
    @Rule(name = " 3  ", description = "number   3  ,  :number is three")
    public class ThreeRule {
      /**
       * Condition:      :  return true,   Action
       *
       * @param number
       * @return
       */
      @Condition
      public boolean isThree(@Fact("number") int number) {
        return number % 3 == 0;
      }
    
      /**
       * Action       
       *
       * @param number
       */
      @Action
      public void threeAction(@Fact("number") int number) {
        System.out.println(number + " is three");
      }
    
      /**
       * Priority:     :return     ,     
       *
       * @return
       */
      @Priority
      public int getPriority() {
        return 1;
      }
    }
    ルール2
    
    @Rule(name = " 8  ")
    public class EightRule {
    
      /**
       *   
       *
       * @param number
       * @return
       */
      @Condition
      public boolean isEight(@Fact("number") int number) {
        return number % 8 == 0;
      }
    
      /**
       *        
       *
       * @param number
       */
      @Action
      public void eightAction(@Fact("number") int number) {
        System.out.println(number + " is eight");
      }
    
      /**
       *         
       *
       * @return
       */
      @Priority
      public int getPriority() {
        return 2;
      }
    }
    ルール3(コンビネーションルール-同時実行)
    
    @Rule(name = " 3 8    ", description = "        ")
    public class ThreeEightRuleUnitGroup extends UnitRuleGroup {
    
      public ThreeEightRuleUnitGroup(Object... rules) {
        for (Object rule : rules) {
          addRule(rule);
        }
      }
    
      @Override
      public int getPriority() {
        return 0;
      }
    }
    ルール4
    
    @Rule(name = "   3     8  ", description = "  number  ")
    public class OtherRule { 
      @Condition
      public boolean isOther(@Fact("number") int number){
        return number % 3 != 0 || number % 8 != 0;
      }
    
      @Action
      public void printSelf(@Fact("number") int number){
        System.out.print(number);
      }
    
      @Priority
      public int getPriority(){
        return 3;
      }
    }
    実行規則
    
    public class ThreeEightRuleLauncher {
    
      public static void main(String[] args) {
        /**
         *         
         *   : skipOnFirstAppliedRule   ,                   
         */
        RulesEngineParameters parameters = new 
        RulesEngineParameters().skipOnFirstAppliedRule(true);
        RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
        //    
        Rules rules = new Rules();
        rules.register(new EightRule());
        rules.register(new ThreeRule());
        rules.register(new ThreeEightRuleUnitGroup(new EightRule(), new ThreeRule()));
        rules.register(new OtherRule());
        Facts facts = new Facts();
        for (int i=1 ; i<=50 ; i++){
          //    ,   name,       @Fact   
          facts.put("number", i);
          //    
          rulesEngine.fire(rules, facts);
          System.out.println();
        }
      }
    }
    例2:MVEL表現に基づくプログラミングモデル
    この例ではMVEL表現でルールを定義する方法を示します。MVELはEasy-Rules MVELモジュールで提供します。このモジュールはMVELを使用して規則を定義するAPIを含んでいます。私たちはここでこれらのAPIを使用します。目的は簡単な店のアプリケーションを実現することです。子供がアルコールを買うことを禁止します。大人の最低年齢は18歳です。ショップの顧客はPerson類で定義されています。
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
      private String name;
    
      private boolean adult;
    
      private int age;
      //getter, setter   
    
    
      public Person(String name, int age) {
        this.name = name;
        this.age = age;
      }
    }
    二つのルールを定義します。
  • 規則1:Personの例を更新し、18歳以上の年齢かどうかを判断し、成人のマークを設定することができます。
  • 規則2:この人は大人かどうかを判断し、子供(つまり大人ではない)からアルコールを買うのを拒否します。
  • 規則1の優先度が規則2より大きいことは明らかです。ルール1のPriorityは1、ルール2のPriorityは2です。このようにルールエンジンが規則を実行する時は優先順位でルールを実行することができます。
    ルール1の定義
    
     Rule ageRule = new MVELRule()
            .name("age rule")
            .description("Check if person's age is > 18 and marks the person as adult")
            .priority(1)
            .when("person.age > 18")
            .then("person.setAdult(true);");
    
    ルール2の定義は、alcohol-rule.ymlファイルに入れます。
    
    name: "alcohol rule" 
    description: "children are not allowed to buy alcohol" 
    priority: 2 
    condition: "person.isAdult() == false" 
    actions: 
     - "System.out.println(\"Shop: Sorry, you are not allowed to buy alcohol\");"
    
    実行規則
    
    public class ShopLauncher {
      public static void main(String[] args) throws Exception {
        //    Person  (Fact)
        Person tom = new Person("Tom", 19);
        Facts facts = new Facts();
        facts.put("person", tom);
    
        //    1
        Rule ageRule = new MVELRule()
            .name("age rule")
            .description("Check if person's age is > 18 and marks the person as adult")
            .priority(1)
            .when("person.age > 18")
            .then("person.setAdult(true);");
        //    2
        Rule alcoholRule = new MVELRuleFactory(new YamlRuleDefinitionReader()).
            createRule(new FileReader(ResourceUtils.getFile("classpath:alcohol-rule.yml")));
    
        Rules rules = new Rules();
        rules.register(ageRule);
        rules.register(alcoholRule);
    
        //        ,     
        RulesEngine rulesEngine = new DefaultRulesEngine();
        System.out.println("Tom: Hi! can I have some Vodka please?");
        rulesEngine.fire(rules, facts);
        System.out.println(JSON.toJSONString(tom));
      }
    }
    
    
    実行結果は以下の通りです。

    この記事は主にeasy-rulesの使用を紹介します。
    原理を深く理解して、githubのソースコードを確認することができます:https://github.com/j-easy/easy-rules
    ここで、java軽量クラスのルールエンジンeasy-rulesについて紹介した文章を使ってここに紹介します。java easury-rulesに関する内容は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。