them's the rules - using a rules engine to wrangle complexity

33
Them’s the Rules by Micah Breedlove Using a Rules Engine to Wrangle Complexity

Upload: micah-breedlove

Post on 09-Apr-2017

712 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

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

Rules EnginesDrools

Open Rules

Jess

Ruler (PHP)

Page 4: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

Some definitions

Page 6: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

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

Business Logic?

Company policies

Legal Regulations

Page 9: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

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

...

Page 12: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

Fixable?Something to …

Abstractly handle multiple conditionsWithMinimal conditional logicand isReusable

Page 14: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

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

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

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

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

$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

Ruler - Elements of the Equation3 Parts

Context

Rule

Execution/Evaluation

Page 21: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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

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

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

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

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

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

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

...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

Questions?

Page 30: Them's the Rules - Using a Rules Engine to Wrangle Complexity

Demo Time

Page 31: Them's the Rules - Using a Rules Engine to Wrangle Complexity

Thanks!

Page 32: Them's the Rules - Using a Rules Engine to Wrangle Complexity

Slides: http://sthen.es/mqh4ub20

Page 33: Them's the Rules - Using a Rules Engine to Wrangle Complexity

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