花痴流口水颜文字_流口水可执行模型
花癡流口水顏文字
可執行模型是對引擎處理的Drools最低級別模型的重新設計。 在當前的系列(最多6.x)中,可執行模型在過去的8年中有機地增長了,從未真正成為最終用戶的目標。 建議那些希望以編程方式編寫規則的人通過代碼生成和目標drl來完成; 這是不理想的。 從來沒有任何驅動程序可以使最終用戶更容易地使用它,因為在Java中廣泛使用匿名類非常麻煩。 借助Java 8和Lambda的這種變化,就有可能制造出最終用戶可以訪問的更具吸引力的模型。
這個新模型是在高級語言的編譯過程中生成的,但也可以單獨使用。 我們的目標是使該可執行模型自成一體,并避免進行進一步的字節碼修改(分析,轉換或生成); 從該模型的角度來看,所有內容均由代碼或高級語言層提供。 例如,索引等必須由參數提供,高級語言在針對可執行模型時會通過分析生成這些參數。
它旨在利用Java 8的lambda很好地映射到Fluent級別的構建者。 這將使其對Java開發人員和語言開發人員更具吸引力。 而且,這將允許獨立于任何語言的低級引擎功能設計和測試。 這意味著我們可以在引擎級別進行創新,而不必擔心語言層。
可執行模型應該足夠通用以映射到多個域。 這將是一個低級數據流模型,您可以在其中處理功能性React式編程模型,但仍可用于從中構建基于規則的系統。
以下示例提供了用于構建可執行模型的流利DSL的第一個視圖:
DataSource persons = sourceOf(new Person("Mark", 37),new Person("Edson", 35),new Person("Mario", 40));Variable<Person> markV = bind(typeOf(Person.class));Rule rule = rule("Print age of persons named Mark").view(input(markV, () -> persons),expr(markV, person -> person.getName().equals("Mark"))).then(on(markV).execute(mark -> System.out.println(mark.getAge())) );前面的代碼定義了一個包含一些人員實例的數據源,并聲明了人員類型的變量markV。 規則本身包含通常的兩部分:LHS由傳遞給view()方法的一組輸入和表達式定義,而RHS是由傳遞給then()方法的lambda表達式定義的動作。
更詳細地分析LHS,語句如下:
input(markV, () -> persons)將人員數據源中的對象綁定到markV變量,并通過對象類進行模式匹配。 從這個意義上講,DataSource可以被視為等同于Drools入口點。
相反的表達:
expr(markV, person -> person.getName().equals("Mark"))使用謂詞定義綁定到markV變量的對象必須滿足的條件才能被引擎成功匹配。 請注意,正如預期的那樣,模式匹配的評估不是通過作為任何種類的分析或編譯過程的結果而生成的約束來執行的,而是僅通過應用實現謂詞的lambda表達式(在這種情況下,人員- > person.getName()。equals(“ Mark”))匹配的對象。 換句話說,前一個DSL會產生一個規則的可執行模型,該模型等效于后續drl的解析結果。
rule "Print age of persons named Mark" whenmarkV : Person( name == "Mark" ) from entry-point "persons" thenSystem.out.println(markV.getAge()); end它還正在開發一個rete構建器,可以使用此DSL定義的規則。 特別是,可以將這些規則添加到CanonicalKieBase中,然后像其他任何普通KieBase一樣從中創建KieSession。
CanonicalKieBase kieBase = new CanonicalKieBase(); kieBase.addRules(rule);KieSession ksession = kieBase.newKieSession(); ksession.fireAllRules();當然,DSL還允許定義更復雜的條件,例如連接:
Variable<Person> markV = bind(typeOf(Person.class)); Variable<Person> olderV = bind(typeOf(Person.class));Rule rule = rule("Find persons older than Mark").view(input(markV, () -> persons),input(olderV, () -> persons),expr(markV, mark -> mark.getName().equals("Mark")),expr(olderV, markV, (older, mark) -> older.getAge() > mark.getAge())).then( on(olderV, markV).execute((p1, p2) -> System.out.println(p1.getName() + " is older than " + p2.getName())) );或存在模式:
Variable<Person> oldestV = bind(typeOf(Person.class)); Variable<Person> otherV = bind(typeOf(Person.class));Rule rule = rule("Find oldest person").view(input(oldestV, () -> persons),input(otherV, () -> persons),not(otherV, oldestV, (p1, p2) -> p1.getAge() > p2.getAge())).then( on(oldestV).execute(p -> System.out.println("Oldest person is " + p.getName())) );這里的not()代表所有表達式的取反,因此上面使用的形式實際上只是以下內容的快捷方式:
not( expr( otherV, oldestV, (p1, p2) -> p1.getAge() > p2.getAge() ) )還已經以以下形式支持累計:
Variable<Person> person = bind(typeOf(Person.class)); Variable<Integer> resultSum = bind(typeOf(Integer.class)); Variable<Double> resultAvg = bind(typeOf(Double.class));Rule rule = rule("Calculate sum and avg of all persons having a name starting with M").view(input(person, () -> persons),accumulate(expr(person, p -> p.getName().startsWith("M")),sum(Person::getAge).as(resultSum),avg(Person::getAge).as(resultAvg))).then(on(resultSum, resultAvg).execute((sum, avg) -> result.value = "total = " + sum + "; average = " + avg) );為了提供最后一個更完整的用例,可以使用此DSL定義經典火災和警報示例的可執行模型,如下所示。
Variable<Room> room = any(Room.class); Variable<Fire> fire = any(Fire.class); Variable<Sprinkler> sprinkler = any(Sprinkler.class); Variable<Alarm> alarm = any(Alarm.class);Rule r1 = rule("When there is a fire turn on the sprinkler").view(input(fire),input(sprinkler),expr(sprinkler, s -> !s.isOn()),expr(sprinkler, fire, (s, f) -> s.getRoom().equals(f.getRoom()))).then(on(sprinkler).execute(s -> {System.out.println("Turn on the sprinkler for room " + s.getRoom().getName());s.setOn(true);}).update(sprinkler, "on") );Rule r2 = rule("When the fire is gone turn off the sprinkler").view(input(sprinkler),expr(sprinkler, Sprinkler::isOn),input(fire),not(fire, sprinkler, (f, s) -> f.getRoom().equals(s.getRoom()))).then(on(sprinkler).execute(s -> {System.out.println("Turn off the sprinkler for room " + s.getRoom().getName());s.setOn(false);}).update(sprinkler, "on") );Rule r3 = rule("Raise the alarm when we have one or more fires").view(input(fire),exists(fire)).then(execute(() -> System.out.println("Raise the alarm")).insert(() -> new Alarm()) );Rule r4 = rule("Lower the alarm when all the fires have gone").view(input(fire),not(fire),input(alarm)).then(execute(() -> System.out.println("Lower the alarm")).delete(alarm) );Rule r5 = rule("Status output when things are ok").view(input(alarm),not(alarm),input(sprinkler),not(sprinkler, Sprinkler::isOn)).then(execute(() -> System.out.println("Everything is ok")) );CanonicalKieBase kieBase = new CanonicalKieBase(); kieBase.addRules(r1, r2, r3, r4, r5);KieSession ksession = kieBase.newKieSession();// phase 1 Room room1 = new Room("Room 1"); ksession.insert(room1); FactHandle fireFact1 = ksession.insert(new Fire(room1)); ksession.fireAllRules();// phase 2 Sprinkler sprinkler1 = new Sprinkler(room1); ksession.insert(sprinkler1); ksession.fireAllRules();assertTrue(sprinkler1.isOn());// phase 3 ksession.delete(fireFact1); ksession.fireAllRules();在此示例中,可能還要注意幾件事:
- 必須執行一些重復操作才能將表達式的參數綁定到評估它的lambda表達式的形式參數。 希望可以在解決此JDK錯誤時使用-parameters編譯參數來克服此問題。
- any(Room.class)是bind(typeOf(Room.class))的快捷方式
- 輸入未聲明數據源。 這是指出這些對象來自默認空DataSource的快捷方式(對應于Drools默認入口點)。 實際上,在此示例中,事實以編程方式插入到KieSession中。
- 使用輸入而不為其提供任何表達式的輸入實際上是input(alarm),expr(alarm,a-> true)的快捷方式
- 以同樣的方式,沒有條件的存在模式,例如not(fire)是not(expr(fire,f-> true))的另一個快捷方式
- Java 8語法還允許將謂詞定義為訪問諸如expr(sprinkler,Sprinkler :: isOn)之類的事實的布爾屬性的方法引用。
- RHS與要執行的代碼塊一起,還提供了一個流暢的接口來定義在觸發規則時必須執行的工作內存操作(插入/更新/刪除)。 特別是,更新還獲得了一個字符串變量,用于報告已更新事實中更改的屬性的名稱,例如update(sprinkler,“ on”)。 由于必須創建可執行模型而無需任何代碼分析,因此必須再次明確提供此信息。
翻譯自: https://www.javacodegeeks.com/2014/07/drools-executable-model.html
花癡流口水顏文字
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的花痴流口水颜文字_流口水可执行模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 源泉插件快捷键命令修改(源泉插件怎么修改
- 下一篇: 告诉我们您想要什么,我们将做到:消费者驱