Jess Rule Engine i JSR 94

1. Pregled

Upotreba mehanizma pravila izvrstan je način da odvojite poslovnu logiku od našeg uzorka i zaštitite naš aplikacijski kôd od poslovnih promjena.

U prethodnom članku o Java Rule Enginesima spomenuli smo specifikaciju JSR 94. Jess Rule Engine ima posebnu važnostkao implementacija pokretačkog programa referentnih pravila za JSR 94, pa pogledajmo ga.

2. Motor Jess Rule

Jess je jedan od najranijih mehanizama za pravilo koji se lako integrira s Javom. Jess koristi poboljšanu implementaciju vrlo učinkovitog algoritma Rete, što ga čini mnogo bržim od jednostavne Java petlje za većinu scenarija.

Pravila se mogu izvršavati iz skupova pravila napisanih u izvornom Jess Rules Languageu, proširenoj sintaksi koja se temelji na Lispu, ili iz opširnijeg XML formata. Upotrijebit ćemo izvorni format.

Postoji IDE zasnovan na Eclipseu (za starije verzije Eclipsea) i izvrsna dokumentacija o korištenju i integraciji Jess s Javom. Postoji čak i sučelje naredbenog retka REPL na kojem možemo isprobati svoje ideje prije stvaranja datoteke s pravilima.

Kao referentni mehanizam pravila za JSR 94, Jess je po definiciji usklađen s JSR 94, iako više nije u aktivnom razvoju.

2.1. Kratka riječ o JSR-u 94

JSR 94 nudi API koji možemo koristiti kako bi nam osigurali neovisnost od bilo kojeg mehanizma pravila koji odaberemo. U naš kôd možemo uključiti bilo koji mehanizam pravila usklađen s JSR 94 i pokrenuti neka pravila bez potrebe za promjenom načina interakcije s mehanizmom pravila u našoj aplikaciji.

To ne znači da će osnovna pravila mehanizma pravila izgledati isto - možda ćemo ih morati prepisati ako promijenimo mehanizam pravila, ali to znači da nećemo trebati prepisivati ​​dijelove aplikacije da bismo koristili novi mehanizam pravila. Jedine promjene koda koje će nam trebati su ažuriranje naziva upravljačkog programa i nekih naziva datoteka pravila.

2.2. Vozač Jess JSR 94

Iako postoji mehanizam referentnih pravila vozač za Jess uključen za JSR 94, sam Jess nije uključen, jer je licencirani komercijalni proizvod. Referentni pokretački program dolazi u org.jcp.jsr94.jess paket, ali noviji upravljački program dostupan je u jess.jsr94 paket kad preuzmemo Jess.

Krenimo s gledanjem Jessine izvorne Java integracije prije nego što krenemo dalje kako bismo vidjeli kako sloj JSR 94 to mijenja.

3. Navedeni primjeri

Prije nego što započnemo integrirati Jess u naš kôd, provjerimo jesmo li ga preuzeli i učinili dostupnim na našoj stazi. Morat ćemo se registrirati za besplatno 30-dnevno probno preuzimanje ako već nemamo licencu.

Dakle, preuzmimo Jess, raspakirajte preuzeto Jess71p2.jari pokrenite jedan od njegovih primjera kako biste bili sigurni da imamo radnu verziju.

3.1. Samostalna Jess

Pogledajmo u Jess71p2 / primjeri imenik, gdje je jess direktorij sadrži neke primjere skupova pravila. The cijena_motor direktorij prikazuje integraciju koja se može izvršiti putem mrava build.xml skripta. Promijenimo naš direktorij na primjer mehanizma za određivanje cijena i pokrenimo program putem test mrava:

cd Jess71p2 / examples / pricing_engine test mrava

Ovo gradi i pokreće primjer cjenovnog pravila pravila:

Datoteka gradnje: Jess71p2 \ examples \ pricing_engine \ build.xml ... test: [java] Predmeti za narudžbu 123: [java] 1 CD Writer: 199,99 ... [java] Predmeti za narudžbu 666: [java] 1 Incredibles DVD: 29,99 [java] Ponude za narudžbu 666: [java] BUILD SUCCESSFUL Ukupno vrijeme: 1 sekunda

3.2. Jess s JSR 94

Sada kada Jess radi, preuzmimo JSR 94, a zatim ga raspakirajte da biste stvorili jsr94-1.0 direktorij s direktorijima ant, doc, lib i src.

raspakirajte jreng-1_0a-fr-spec-api.zip

To nam daje JSR 94 API i Jess referentni pokretački program, ali ne dolazi s licenciranom Jess implementacijom, pa ako sada pokušamo pokrenuti primjer, dobit ćemo sljedeću pogrešku:

Pogreška: Nije moguće pronaći referentnu implementaciju Jess.

Dakle, dodajmo implementaciju Jess reference, jess.jar, koji je došao kao dio Jess71p2 koji smo ranije preuzeli i kopirao ga u direktorij JSR 94 lib, a zatim pokrenite primjer:

cp Jess71p2 / lib / jess.jar jsr94-1.0 / lib / java -jar jsr94-1.0 / lib / jsr94-example.jar

U primjeru se pokreću neka pravila za određivanje preostalog kredita kupca prilikom plaćanja računa:

Administratorski API stečen RuleAdministrator: [zaštićen e-poštom] ... Runtime API stečen RuleRuntime: [zaštićen e-poštom] Rezultat kreditnog ograničenja klijenta: 3000 ... Iznos fakture 2: 1750 status: plaćeno Otpuštena sesija Stateful Rule.

4. Integriranje Jess s Javom

Sad kad smo preuzeli Jess i JSR 94 i pokrenuli neka pravila i nativno i putem JSR-a, pogledajmo kako integrirati Jess-ov skup pravila u Java program.

U našem primjeru započet ćemo izvršavanjem jednostavne datoteke Jess pravila, hellojess.clp, iz Java koda, a zatim pogledajte drugu datoteku pravila, bonus.clp, koji će koristiti i modificirati neke od naših objekata.

4.1. Ovisnost Mavena

Za Jess ne postoji ovisnost o Mavenu, pa ako to već nismo učinili, preuzmimo i raspakirajte Jess teglu (jess.jar) i mvn instalirati u naše lokalno spremište Maven:

mvn install: install-file -Dfile = jess.jar -DgroupId = gov.sandia -DartifactId = jess -Dversion = 7.1p2 -Dpackaging = jar -DgeneratePom = true

Tada ga možemo dodati kao ovisnost na uobičajeni način:

 gov.sandia jess 7.1p2 

4.2. Datoteka s pravilima Jess

Dalje, izradimo najjednostavnije datoteke s pravilima za ispis poruke. Datoteku pravila spremit ćemo kao zdravo.clp:

(ispis t "crlf" Hello from Jess! ")

4.3. Jess Rule Engine

Ajmo sada stvoriti primjerak Jess Rete pravilo motora, resetirati () u početno stanje, učitajte pravila u zdravo.clp, i pokrenite ih:

javna klasa HelloJess {public static void main (String [] args) baca JessException {Rete engine = new Rete (); engine.reset (); engine.batch ("hellojess.clp"); engine.run (); }

Za ovaj jednostavan primjer upravo smo dodali potencijal JessException našem glavni metoda baca klauzula.

Kada pokrenemo naš program, vidjet ćemo izlaz:

Pozdrav od Jess!

5. Integriranje Jess u Javu s podacima

Sada kada je sve ispravno instalirano i možemo pokretati pravila, pogledajmo kako dodajemo podatke za obradu mehanizma pravila i kako dohvaćamo rezultate.

Prvo će nam trebati neke Java satove za rad, a zatim novi skup pravila koji ih koristi.

5.1. Model

Stvorimo neke jednostavne Pitanje i Odgovor klase:

pitanje javne klase {pitanje privatnog niza; privatna int ravnoteža;  // geteri i postavljači  javno pitanje (nisko pitanje, int balans) {this.question = question; this.balance = ravnoteža; }} odgovor javne klase {odgovor privatni niz; private int newBalance;  // geteri i postavljači  javni odgovor (String odgovor, int newBalance) {this.answer = answer; this.newBalance = newBalance; }}

5.2 Jess pravilo s ulazom i izlazom

Sada, kreirajmo jednostavni Jessov skup pravila pod nazivom bonus.clp da ćemo proći a Pitanje i primiti Odgovor iz.

Prvo, mi uvoz naše Pitanje i Odgovor klase, a zatim upotrijebite Jessinu deftemplate funkcija koja ih čini dostupnima mehanizmu pravila:

(import com.baeldung.rules.jsr94.jess.model. *) (deftemplate Pitanje (deklarirati (iz klase Pitanje))) (deftemplate Odgovor (deklarirati (iz klase Odgovor)))

Obratite pažnju na upotrebu zagrada koje označavaju pozive Jess funkcije.

Sada, iskoristimo defrule dodati jedno pravilo izbjeći-prekoračenje u Jessinom proširenom Lisp formatu koji nam daje bonus od 50 USD ako je stanje u našem Pitanje je ispod nule:

(defrule izbjegavanje prekoračenja "Dajte 50 $ onome tko je prekoračio"? q <- (Pitanje {saldo (dodati (novi odgovor "Overdrawn bonus" (+? q.balance 50))))

Ovdje je „?” veže objekt na varijablu q kada se uvjeti s desne strane "<-“ podudaranje. U ovom slučaju, tada mehanizam pravila pronalazi a Pitanje koja ima ravnoteža manje od 0.

Kad se dogodi, tada akcije s desne strane "=>” pokreću se pa motor dodatis a novi odgovor prigovor radnoj memoriji. Dajemo mu dva potrebna argumenta konstruktora: "Prekoračeni bonus" za odgovor parametar i a (+) funkcija za izračunavanje newAmount parametar.

5.3. Manipuliranje podacima s Jess Rule Engineom

Možemo koristiti dodati() za dodavanje pojedinačnih predmeta u radnu memoriju našeg mehanizma pravila, ili Dodaj Sve() za dodavanje zbirke podataka. Iskoristimo dodati() da dodate jedno pitanje:

Pitanje za pitanje = novo pitanje ("Mogu li dobiti bonus?", -5); engine.add (podaci);

Sa svim našim podacima na mjestu, izvršimo naša pravila:

engine.run ();

Jess Rete motor će raditi svoju čaroliju i vratiti se kad se izvrše sva relevantna pravila. U našem ćemo slučaju imati Odgovor istražiti.

Koristimo a jess.Filter izvući naše Odgovor iz pravila motora u Iterativ rezultat objekt:

Rezultati iteratora = engine.getObjects (novi jess.Filter.ByClass (Answer.class)); while (results.hasNext ()) {Answer answer = (Answer) results.next (); // obraditi naš odgovor}

U našem jednostavnom primjeru nemamo referentnih podataka, ali kad ih imamo, možemo koristiti a WorkingMemoryMarker i motor.mark () za označavanje stanja radne memorije stroja za pravila nakon dodavanja podataka. Tada možemo nazvati motor.resetToMark pomoću našeg markera za vraćanje radne memorije u stanje „učitavanja“ i učinkovitu ponovnu upotrebu mehanizma pravila za drugačiji skup objekata:

Marker WorkingMemoryMarker; // učitavanje referentnih podataka marker = engine.mark (); // učitavanje specifičnih podataka i pokretanje pravila engine.resetToMark (marker);

Sada, pogledajmo kako pokrećemo isti skup pravila koristeći JSR 94.

6. Korištenje JSR 94 za integriranje Jess Rule Enginea

JSR 94 standardizira način na koji naš kod komunicira s mehanizmom pravila. To olakšava promjenu mehanizma pravila bez značajnijeg mijenjanja aplikacije ako se pojavi bolja alternativa.

API JSR 94 dolazi u dva glavna paketa:

  • javax.rules.admin - za učitavanje upravljačkih programa i pravila
  • javax.rules - za pokretanje pravila i izdvajanje rezultata

Pogledat ćemo kako koristiti nastavu u obje ove.

6.1. Ovisnost Mavena

Prvo, dodajmo Mavenovu ovisnost za jsr94:

 jsr94 jsr94 1.1 

6.2. API za administraciju

Da bismo počeli koristiti JSR 94, moramo instancirati a RuleServiceProvider. Stvorimo jedan, prosljeđujući ga našem upravljaču Jess pravila:

Niz RULE_SERVICE_PROVIDER = "jess.jsr94"; Class.forName (RULE_SERVICE_PROVIDER + ".RuleServiceProviderImpl"); RuleServiceProvider ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider (RULE_SERVICE_PROVIDER);

Ajmo sada Jessin JSR 94 Administrator pravila, učitajte naš primjer pravila u JSR 94 RuleExecutionSet, i registrirajte ga za izvršenje s URI-jem po našem izboru:

RuleAdministrator ruleAdministrator = serviceProvider.getRuleAdministrator (); InputStream ruleInput = JessRunner.class.getResourceAsStream (rulesFile); HashMap vendorProperties = novi HashMap (); RuleExecutionSet ruleExecutionSet = ruleAdministrator .getLocalRuleExecutionSetProvider (vendorProperties) .createRuleExecutionSet (ruleInput, vendorProperties); String rulesURI = "rules: // com / baeldung / rules / bonus"; ruleAdministrator.registerRuleExecutionSet (rulesURI, ruleExecutionSet, vendorProperties);

Jess vozaču ne trebaju vendorProperties karta kojoj smo dobavili Administrator pravila, ali to je dio sučelja, a drugi dobavljači ga mogu zahtijevati.

Sad kad je naš dobavljač mehanizma pravila, Jess, inicijaliziran i naš skup pravila registriran, gotovo smo spremni pokrenuti naša pravila.

Prije nego što ih možemo pokrenuti, trebaju nam instanca izvođenja i sesija za njihovo pokretanje. Dodajmo i rezervirano mjesto, izračunajte rezultate (), jer gdje će se magija dogoditi i otpustite sesiju:

RuleRuntime ruleRuntime = ruleServiceProvider.getRuleRuntime (); StatelessRuleSession statelessRuleSession = (StatelessRuleSession) ruleRuntime.createRuleSession (rulesURI, nova HashMap (), RuleRuntime.STATELESS_SESSION_TYPE); izračunatiResultate (statelessRuleSession); statelessRuleSession.release ();

6.3. API izvršenja

Sad kad imamo sve na svom mjestu, krenimo u implementaciju izračunatiRezultate za pružanje naših početnih podataka, izvršavanje naših pravila u sesiji bez državljanstva i izdvajanje rezultata:

Podaci s popisa = novi ArrayList (); data.add (novo pitanje ("Mogu li dobiti bonus?", -5)); Popis rezultata = statelessRuleSession.executeRules (podaci);

Budući da je JSR 94 napisan prije nego što se pojavio JDK 5, API ne koristi generičke lijekove, pa neka je samo Iterator da biste vidjeli rezultate:

Iterator itr = results.iterator (); while (itr.hasNext ()) {Objekt obj = itr.next (); if (obj instanceof Answer) {int answerBalance = ((Answer) obj) .getCalculatedBalance ()); }}

U našem smo primjeru koristili sesiju bez državljanstva, ali možemo i stvoriti StatefuleRuleSession ako želimo održavati stanje između zazivanja.

7. Zaključak

U ovom smo članku naučili kako integrirati Jessov mehanizam pravila u našu aplikaciju pomoću Jessinih matičnih klasa i, uz malo više napora, pomoću JSR 94. Vidjeli smo kako se poslovna pravila mogu odvojiti u zasebne datoteke koje se obrađuju po pravilu mehanizma kada se naša aplikacija izvodi.

Ako imamo pravila za istu poslovnu logiku, napisana za drugi mehanizam pravila koji je u skladu s JSR 94, tada možemo jednostavno dodati upravljački program za naš alternativni mehanizam pravila i ažurirati naziv upravljačkog programa koji bi naša aplikacija trebala koristiti i ne bi trebale biti daljnje promjene koda potrebno.

Više detalja nalazi se na jess.sandia.gov za ugradnju Jess u Java aplikaciju, a Oracle ima korisni vodič za početak korištenja Java Rule Engine API (JSR 94).

Kao i obično, kod koji smo pogledali u ovom članku dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found