Them's the Rules - Using a Rules Engine to Wrangle Complexity
-
Upload
micah-breedlove -
Category
Software
-
view
712 -
download
2
Transcript of Them's the Rules - Using a Rules Engine to Wrangle Complexity
![Page 1: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/1.jpg)
Them’s the Rules
byMicah Breedlove
Using a Rules Engine to Wrangle Complexity
![Page 2: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/2.jpg)
PHP Dev since ‘98Symfony Evangelist
@druid628http://micah.breedlove.in/
Sr. Developer / Team Lead @ iostudio
Who is this guy?
![Page 3: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/3.jpg)
Rules EnginesDrools
Open Rules
Jess
Ruler (PHP)
![Page 4: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/4.jpg)
Ruler Written by Justin Hileman(BobTheCow)
GitHub: https://github.com/bobthecow/Ruler
Packagist: ruler/ruler
![Page 5: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/5.jpg)
Some definitions
![Page 6: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/6.jpg)
Conditional Logic“hypothetical logic (of a proposition) consisting of two component propositions... so that the proposition is false only when the antecedent is true and the consequent false.”
How we handle the unknown.
![Page 7: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/7.jpg)
Rules Engines“A business rules engine is a software system that executes one or more business rules in a runtime production environment.”
“An added layer of complexity to carry out, often complicated, business logic of the application”
in other words...
![Page 8: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/8.jpg)
Business Logic?
Company policies
Legal Regulations
![Page 9: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/9.jpg)
ExamplesDiscounts on products purchased
Combination of productsSubscribed services
Additional FeesGeographical assessmentRisk assessment
![Page 10: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/10.jpg)
What is wrong with this?if ( $obj->getName() == ‘abc’) { } elseif ($obj->getName() == ‘def’) {} elseif ($obj->getName() == ‘ghi’) { } elseif ($obj->getName() == ‘jkl’ ) {} elseif ($obj->getName() == ‘mno’ ) {} elseif ($obj->getName() == ‘pqr’ && $obj->getClient()->getCategory() !== ‘hotChkn’) {}elseif ($obj->getName() == ‘Hg(CNO)2’ && $obj->getClientKey() == ‘tuco’){}elseif ($obj->getName() == ‘blueSky’ && $obj->getClientKey() == ‘losPollosHermanos’) {} elseif ($obj->getName() == ‘blueSky’ && $obj->getClientKey() == ‘heisenberg’){}
![Page 11: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/11.jpg)
...
![Page 12: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/12.jpg)
Should be kept trimmed, maintained and under control
Or else...
Pandemonium Ensues
Conditional statements are like Kudzu
![Page 13: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/13.jpg)
Fixable?Something to …
Abstractly handle multiple conditionsWithMinimal conditional logicand isReusable
![Page 14: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/14.jpg)
Simplifies a block into a generic block
Support more than a simple/singular condition
Abstraction
![Page 15: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/15.jpg)
Minimize Conditional LogicDrop the ever-building conditionals
Replace with smaller defined block
![Page 16: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/16.jpg)
ReusabilityAbility to support all existing conditions
Individual rules can be evaluated in other RuleSets
![Page 17: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/17.jpg)
The saga begins… if ($bond->getClient()== ‘client1’ && $event->getName() == ‘bond.create’) {
$this->calculateClient1BondAdjustments($bond);} elseif ($bond->getClient() == ‘client1’ && $event->getName() == ‘payment.made’) {
$this->calculateClient1Payment($bond, $payment);} elseif ($bond->getClient() == ‘client2’ && $event->getName() == ‘bond.create’) {
$this->calculateClient2BondAdjustments($bond);} elseif ($bond->getClient() == ‘client3’ && $event->getName() == ‘bond.create’) {
$this->calculateClient3BondAdjustments($bond);} ...
![Page 18: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/18.jpg)
What We NeedIf a Bond is made in Collegedale
A $25 fee should be assessed
![Page 19: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/19.jpg)
$rule = $ruleFactory->getBondRules();$clientRule = [
‘district’ => ‘collegedale’, ‘district_fee’ => ‘25’,‘fee_adjustment’ => ‘+’ ];
$context = new Context([ ‘bond_district’ => $bond->getDistrict(),‘district’ => $clientRule[‘district’],
‘district_fee’ => $clientRule[‘district_fee’],‘fee_adjustment’ => $clientRule[‘’fee_adjustment’] ]);
$rule->execute($context);
Rule Elements
![Page 20: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/20.jpg)
Ruler - Elements of the Equation3 Parts
Context
Rule
Execution/Evaluation
![Page 21: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/21.jpg)
Context - All Applicable Data
Variable Data:‘bond_district’ => ‘collegedale’,
Control Data:‘district’ => ‘collegedale’, ‘district_fee’ => ‘25’,‘fee_adjustment’ => ‘+’
Variable Data Request User Specific
(includes session)
Control Data Specific to the Rule
![Page 22: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/22.jpg)
Rule
$rule = $rb->create( $rb['bond_district']->EqualTo($rb['district'])
);
How the Context Stacks UpHow to evaluate the dataWhat to evaluate
Variable Data:‘bond_district’ => ‘collegedale’,
Control Data:‘district’ => ‘collegedale’, ‘district_fee’ => ‘25’,‘fee_adjustment’ => ‘+’
![Page 23: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/23.jpg)
Rule (cont.)Compound Rules
$rule = $rb->create( $rb->LogicalAnd($rb['bond_district']->EqualTo($rb['district']),$rb['bond_amount']->GreaterThan('20000')) );
![Page 24: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/24.jpg)
Evaluation/ExecutionEvaluate - (boolean) Did it meet the condition?
Execution - (void) If it’s true do something
![Page 25: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/25.jpg)
Evaluation Example
Rule:$rule = $rb->create(
$rb['bond_district']->EqualTo($rb['district']) );
$status = $rule->evaluate($context);echo $status; // true
Control Data:‘district’ => ‘collegedale’, ‘district_fee’ => ‘25’,‘fee_adjustment’ => ‘+’
Variable Data:‘bond_district’ => ‘collegedale’
![Page 26: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/26.jpg)
Execution Example
$rule->execute($context);// output: An additional mileage fee will be charged.
Control Data:‘district’ => ‘collegedale’, ‘district_fee’ => ‘25’,‘fee_adjustment’ => ‘+’
Variable Data:‘bond_district’ => ‘collegedale’
Rule:$rule = $rb->create(
$rb['bond_district']->EqualTo($rb['district']),function() {
echo 'An additional mileage fee will be charged.';} );
![Page 27: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/27.jpg)
if ($bond->getClient()== ‘client1’ && $event->getName() == ‘bond.create’) {$this->calculateClient1BondAdjustments($bond);
} elseif ($bond->getClient() == ‘client1’ && $event->getName() == ‘payment.made’) {$this->calculateClient1Payment($bond, $payment);
} elseif ($bond->getClient() == ‘client2’ && $event->getName() == ‘bond.create’) {$this->calculateClient2BondAdjustments($bond);
} elseif ($bond->getClient() == ‘client3’ && $event->getName() == ‘bond.create’) {$this->calculateClient3BondAdjustments($bond);
} ...
Finally this…
![Page 28: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/28.jpg)
...becomes this
$ruleObject = $rulesRepo->get($event->getName()); // assume bond.create$context = $ruleObject->getContext();$context[‘bond’] = $bond;$rule = $ruleObject->getRule();$rule->execute($context); // one rule to rule them all
![Page 29: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/29.jpg)
Questions?
![Page 30: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/30.jpg)
Demo Time
![Page 31: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/31.jpg)
Thanks!
![Page 33: Them's the Rules - Using a Rules Engine to Wrangle Complexity](https://reader031.fdocuments.us/reader031/viewer/2022030307/58ea279b1a28abf9018b5c4d/html5/thumbnails/33.jpg)
citationsJesse (Breaking Bad) - http://replygif.net/i/1323.gifKudzu - http://2.bp.blogspot.com/_RTswKzWDHeM/SE198zJTgzI/AAAAAAAAA80/ZKj4haQbiSE/s320/kudzu+house.jpgMC Hammer - http://24.media.tumblr.com/26d1484f43ff55401f8ead9d03432bb9/tumblr_moctg0LbmC1sn8pc2o1_400.gif