<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    在路上

    路上有驚慌,路上有理想

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      28 Posts :: 1 Stories :: 10 Comments :: 0 Trackbacks
    對于做軟件的人來說,唯一不變的就是變化。此為行業真理。而對于復雜業務系統的邏輯組件的定義不得不多考慮一下業務的可擴展性,來應對客戶的變化。選擇Rule Engine是一個不錯的方案。

    Drools 是用 Java 語言編寫的開放源碼規則引擎。Drools 允許使用聲明方式表達業務邏輯??梢允褂梅?XML 的本地語言編寫規則(這點很重要,本人之前曾用過自己公司的一套業務規則組件,無論是編寫還是調試都很麻煩),從而便于學習和理解。并且,還可以將 Java 代碼直接嵌入到規則文件中,使Drools 更加吸引人。簡單的概括,就是簡單使用,易于理解。而且它是免費的。

    1.rule文件:
    rule "rule name"  
        no-loop
        when
          customer : Customer( state == CustomerState.UNCENSORED )     
        then
            customer.setState(CustomerState.AUDITING);
            CustomerTask task=new CustomerTask();
            Post law=userService.getPostByPostCode(Constants.PostCode.ROOT_LAW);
            task.setAuditorPost(law);
            task.setEntityState(CustomerState.AUDITING);
            task.setEntityId(customer.getId());
            task.setEntityCode(String.valueOf(customer.getId()));
            task.setEntityType(Customer.class.getSimpleName());
            task.setTitle(customer.getName()+" test");
            taskService.assignmentTask(task);
            logger.info("CustomerTask Submit auditorTitle:" + task.getAuditorTitle());
    end

    這里面有個狀態的條件判斷state == CustomerState.UNCENSORED ,then 關鍵字后面的便是符合條件的處理邏輯,只要是java程度都可以看懂,比xml類的rule文件好懂了許多。

    接下來
    語法說明:


    文件頭部分:
    package drools.java.demo;定義包名,等同于命名空間
    import drools.java.demo.Machine;導入java類
    global java.util.List myGlobalList;此關鍵字讓規則引擎知道,myGlobalList對象應該可以從規則中訪問.
    function:
    類似于公用方法的抽象,如下定義后,各個同一文件下的rule都可以使用
    function void setTestsDueTime(Machine machine, int numberOfDays) {
        setDueTime(machine, Calendar.DATE, numberOfDays);
    }
    rule:定義了一個規則

    rule "<name>"
    <attribute>*
    when
    <conditional element>*
    then
    <action>*
    end




    <name> 即rule的名字標識

    <attribute>:

    常用的屬性:
    no-loop :true 條件結果更改后,修改此條件且定義為no-loop:true的規則不會再重新執行。
    lock-on-active:true 可以看作是no-loop的加強版,當條件結果更改后,不但修改此條件的規則不會重新執行,文件中的任何規則(其 active-lock 屬性被設為 true)不會重新執行。
    salience:100 使用它可以讓規則執行引擎知道應該啟動規則的結果語句的順序。具有最高顯著值的規則的結果語句首先執行;具有第二高顯著值的規則的結果語句第二執行,依此類推。當您需要讓規則按預定義順序啟動時,這一點非常重要。

    其他屬性的解釋請見http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/drools-expert/html_single/index.html#d0e2607

    when:填寫條件的地方,比如:
    Cheese( type == "stilton", price < 10, age == "mature" )或

    Cheese( type == "stilton" && price < 10, age == "mature" )

    then:業務規則的地方,略。

    2.用法

    規則文件定義好后,就該是怎么使用它了


    如上圖,file rule定義好后,就該是如何使用它了。最重要的兩個類RuleBase和WorkingMemory

    下面是一個example:
    public class RulesEngine {
        private RuleBase rules;
        private boolean debug = false;
        public RulesEngine(String rulesFile) throws RulesEngineException {
            super();
            try {
                // Read in the rules source file
                Reader source = new InputStreamReader(RulesEngine.class
                        .getResourceAsStream("../../rules/" + rulesFile));

                // Use package builder to build up a rule package
                PackageBuilder builder = new PackageBuilder();

                // This will parse and compile in one step
                builder.addPackageFromDrl(source);

                // Get the compiled package
                Package pkg = builder.getPackage();

                // Add the package to a rulebase (deploy the rule package).
                rules = RuleBaseFactory.newRuleBase();
                rules.addPackage(pkg);

            } catch (Exception e) {
                throw new RulesEngineException(
                        "Could not load/compile rules file: " + rulesFile, e);
            }
        }
        public RulesEngine(String rulesFile, boolean debug)
                throws RulesEngineException {
            this(rulesFile);
            this.debug = debug;
        }
        public void executeRules(WorkingEnvironmentCallback callback) {
            WorkingMemory workingMemory = rules.newStatefulSession();
            if (debug) {
                workingMemory
                        .addEventListener(new DebugWorkingMemoryEventListener());
            }
            callback.initEnvironment(workingMemory);
            workingMemory.fireAllRules();
        }
    }
    RulesEngine構造方法演示了如何去讀入一個rule文件,并構建了一個RuleBase對象(RuleBase 是一個包含了rule文件的所有規則的集合)
    executeRules方法定義了如何使用規則文件中定義的那些內容,用RuleBase構建一個WorkingMemory對象,再執行fireAllRules()方法。
    WorkingMemory 代表了與rulebase鏈接的session會話,也可以看作是工作內存空間。如果你要向內存中插入一個對象可以調用insert()方法,同理,更新一個對象使用update()方法。WorkingMemory還有一個setGlobal()方法,用來設置規則內可以引用的對象(相當于規則的全局變量)。

    3.小技巧

      可以一次把所有的rule文件都載入內存中存放,這樣就不用每次執行都讀取文件。
      如果規則文件被修改,也可以用過一個方法來判斷是否需要重新載入rule文件
      比如:根據文件的最后修改時間,與內存中對應對象的時間做比較
    public boolean hasChange(List<RuleFile> ruleFileList){
            for(RuleFile ruleFile:ruleFileList){
                if(!ruleFile.getLastModifyTime().equals(ruleFileMap.get(ruleFile.getFileName()).getLastModifyTime())){
                    return true;
                }
            }
            return false;
        }

    注:具體的helloWorld 請見http://www.ibm.com/developerworks/cn/java/j-drools/#listing12,比我說得好多了。
    posted on 2010-09-25 17:48 阮步兵 閱讀(5254) 評論(0)  編輯  收藏 所屬分類: OpenSource
    主站蜘蛛池模板: 岛国av无码免费无禁网站| 亚洲&#228;v永久无码精品天堂久久 | 亚洲A∨精品一区二区三区下载| 天天摸夜夜摸成人免费视频| 最好2018中文免费视频| 亚洲阿v天堂在线| 永久免费毛片在线播放| 免费看一级一级人妻片| 亚洲五月六月丁香激情| 在线播放高清国语自产拍免费| 久久成人永久免费播放| 亚洲a级在线观看| 亚洲第一区精品观看| 最近2019中文字幕免费大全5 | 国产高潮久久免费观看| 久久亚洲sm情趣捆绑调教| 国产伦精品一区二区三区免费下载| 久久国产乱子伦精品免费一 | 污污网站免费观看| 亚洲国产欧洲综合997久久| 亚洲无线码一区二区三区| 免费可以看黄的视频s色| 一级日本高清视频免费观看| 亚洲成AV人片久久| 中文字幕亚洲不卡在线亚瑟| 欧美在线看片A免费观看| 成人爽a毛片免费| 亚洲av日韩av永久无码电影| 内射少妇36P亚洲区| 亚洲视频在线一区二区| 女人让男人免费桶爽30分钟| 三年片在线观看免费观看大全动漫 | 四虎永久免费影院| 在线视频免费观看爽爽爽| 成人毛片100免费观看| 国产亚洲综合久久| 亚洲最大中文字幕无码网站| 亚洲天堂中文字幕| 在线观看亚洲精品福利片| 国产成人免费ā片在线观看| 国产91免费视频|