约束流–没有Drools规则语言的现代Java约束
傳統(tǒng)上,要使用OptaPlanner進(jìn)行擴(kuò)展,您必須學(xué)習(xí)DRL。 不再。 借助受Java 8 Streams和SQL啟發(fā)的新Constraints Streams API,您現(xiàn)在可以用Java (或Kotlin或Scala) 編寫(xiě)約束,并且仍然可以從增量計(jì)算中受益。
在下面,約束流(CS)仍使用強(qiáng)大的Drools引擎。 我們也仍然完全支持得分DRL。 它們不被棄用。
讓我們從一個(gè)例子開(kāi)始。 在護(hù)士排班中,為了避免將班次分配給員工Ann ,您可以在DRL中編寫(xiě)以下約束:
rule "Don't assign Ann" when Shift(getEmployee().getName() == "Ann" ) then scoreHolder.addSoftConstraintMatch(kcontext, - 1 ); end這在使用約束流的Java中是相同的約束:
Constraint constraint = constraintFactory .from(Shift. class ) .filter(shift -> shift.getEmployee().getName().equals( "Ann" )) .penalize( "Don't assign Ann" , HardSoftScore.ONE_SOFT);如果您熟悉SQL或Java 8流,則應(yīng)該看起來(lái)很熟悉。 給定一個(gè)有四個(gè)班次的潛在解決方案(其中兩個(gè)分配給Ann ),這些班次將通過(guò)約束流流動(dòng),如下所示:
這種寫(xiě)約束的新方法有幾個(gè)好處:
增量計(jì)算
首先,與EasyScoreCalculator不同,約束流仍然像DRL一樣應(yīng)用增量分?jǐn)?shù)計(jì)算來(lái)進(jìn)行橫向擴(kuò)展。 例如,當(dāng)一個(gè)移動(dòng)將雇員換兩班時(shí),僅計(jì)算增量。 這是巨大的可擴(kuò)展性收益:
索引編制
當(dāng)JOIN多個(gè)類型時(shí),就像SQL JOIN運(yùn)算符一樣,約束流在索引上應(yīng)用哈希查找以更好地?cái)U(kuò)展:
IDE支持
因?yàn)镃onstraintsStreams是用Java語(yǔ)言編寫(xiě)的,所以它們背負(fù)了非常強(qiáng)大的工具支持。
代碼突出顯示,代碼完成和調(diào)試工作正常:
代碼突出顯示
IntelliJ IDEA Ultimate中的DRL代碼:
對(duì)于相同的約束,在IntelliJ IDEA Ultimate中使用約束流的Java代碼:
代碼完成
約束流的代碼完成:
當(dāng)然,所有API方法都具有Javadocs。
調(diào)試
在ConstraintStream的filter()添加一個(gè)斷點(diǎn):
在調(diào)試時(shí)診斷問(wèn)題:
Java語(yǔ)法
用約束流用Java編寫(xiě)的約束,無(wú)論好壞,都遵循Java語(yǔ)言規(guī)范(JLS)。 當(dāng)使用來(lái)自Kotlin或Scala的約束流時(shí),適用類似的邏輯。
在DRL和約束流之間遷移時(shí),請(qǐng)注意DRL和Java之間的一些區(qū)別:
- DRL的==運(yùn)算符在Java中轉(zhuǎn)換為equals() 。
- 除了getter,DRL還允許MVEL表達(dá)式轉(zhuǎn)換為Java中的getter。
例如,此DRL具有name和== :
rule "Don't assign Ann" when Employee(name == "Ann" ) then ... end但是,對(duì)于完全相同的約束,Java變量具有g(shù)etName()和equals() :
constraintFactory.from(Employee. class ) .filter(employee -> employee.getName().equals( "Ann" )) .penalize( "Don't assign Ann" , ...);進(jìn)階功能
Constraint Streams API使我們可以添加語(yǔ)法糖和強(qiáng)大的新概念,這些概念專門為幫助您構(gòu)建復(fù)雜的約束而量身定制。
為了突出其中之一,讓我們看一下功能強(qiáng)大的groupBy方法:
與SQL GROUP BY運(yùn)算符或Java 8 Stream Collector相似,它支持sum() , count() , countDistinct() , min() , max() , toList()甚至自定義函數(shù),同樣也不會(huì)損失增量分?jǐn)?shù)計(jì)算。
約束流的未來(lái)工作
首先,非常感謝Luká?Petrovicky在Constraints Streams上所做的所有工作!
但這僅僅是開(kāi)始。 我們?cè)O(shè)想了更高級(jí)的功能,例如負(fù)載平衡/公平方法,以使此類約束更易于實(shí)現(xiàn)。
目前,我們的首要任務(wù)是簡(jiǎn)化對(duì)隔離的單元測(cè)試的單元。 考慮測(cè)試驅(qū)動(dòng)設(shè)計(jì)。 敬請(qǐng)關(guān)注!
翻譯自: https://www.javacodegeeks.com/2020/04/constraint-streams-modern-java-constraints-without-the-drools-rule-language.html
總結(jié)
以上是生活随笔為你收集整理的约束流–没有Drools规则语言的现代Java约束的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: hibernate jpa_JPAHib
- 下一篇: java拦截器项目应用_使用拦截器分析J