62
Obey the Rules! Understand business rules processing theory Review real world case studies on client side rules processing. Walk through a simple a client-side rules processing engine written in Flex 3.0

Obey The Rules: Implementing a Rules Engine in Flex

  • Upload
    rj-owen

  • View
    4.820

  • Download
    2

Embed Size (px)

DESCRIPTION

A presentation I gave with Drew McLean at 360|Flex 2010 in San Jose. The presentation covers how to develop a client-side rules engine using Adobe Flex. We discuss rules engine theory and give three sample implementations. I apologize that I cannot upload source files here - please contact us for more information.

Citation preview

Page 1: Obey The Rules: Implementing a Rules Engine in Flex

Obey the Rules!Understand business rules processing theory

Review real world case studies on client side rules processing.

Walk through a simple a client-side rules processing engine written in Flex 3.0

Page 2: Obey The Rules: Implementing a Rules Engine in Flex

What is a rules engine?

Page 3: Obey The Rules: Implementing a Rules Engine in Flex

Rules engines

• are mechanisms for executing business rules in a runtime production environment.

• separate business rules from application logic (encapsulation!)

• are often deployed on a web application server.

• are packaged as components with the ability to create, define, classify and manage business rules.

Page 4: Obey The Rules: Implementing a Rules Engine in Flex

• are formalized specifications of business processes

• are statements that define or constrain some aspect an organization

Business rules

Business process: keep stores well stocked.Business rule: If the number of shirts in a store gets below 15, order more.

Page 5: Obey The Rules: Implementing a Rules Engine in Flex

• Business rules change more frequently than the rest of the application code.

• Business rules require input and management by an organization (human).

• Business rules can be completely externalized from the application (code) or carefully organized

• This is accomplished through good application architecture, which may or may not include a rules engine

Keep ‘em Separated

Page 6: Obey The Rules: Implementing a Rules Engine in Flex
Page 7: Obey The Rules: Implementing a Rules Engine in Flex

Why use a rules engine in your application?

• Lower the cost in modifying business logic

• Shorten development time and maintenance time

• Rules are externalized so can easily shared across multiple applications

• Changes can be made faster and with less risk

• Increase productivity and flexibility in your business

• Lots of business-specific code or some well organized XML rules?

Page 8: Obey The Rules: Implementing a Rules Engine in Flex

How are rules defined and implemented?

Page 9: Obey The Rules: Implementing a Rules Engine in Flex

Typical workflow from business to technology

The organization defines the business processes.

Page 10: Obey The Rules: Implementing a Rules Engine in Flex

Typical workflow from business to technology

A business analyst translates business practices into business rule statements, constraints and actions.

Page 11: Obey The Rules: Implementing a Rules Engine in Flex

Typical workflow from business to technology

The software developer implements the rules engine component in the application.

The actions and triggers are implemented by the developer.

The application is deployed by a developer with the rules externalized

Page 12: Obey The Rules: Implementing a Rules Engine in Flex

Typical workflow from business to technology

The organization changes some business processes.

Page 13: Obey The Rules: Implementing a Rules Engine in Flex

Typical workflow from business to technology

If the business process doesn’t require new actions, anyone, including this silly intern with a small desk, can update the rules engine. Win.

Page 14: Obey The Rules: Implementing a Rules Engine in Flex

Why use a client-side rules engine in your Flex RIA?

• Provide an experience that is more contextual and unique to the user

• Remove server dependencies for processing business rules logic.

• Do not have to recompile your .SWF when business logic changes.

• Quicker response to user input that triggers rules.

Page 15: Obey The Rules: Implementing a Rules Engine in Flex

How do rules engines work?

Page 16: Obey The Rules: Implementing a Rules Engine in Flex

Rules Engine Anatomy

• Facts are input to the engine; statements about the system. Often key/value pairs.

• shirts.quantity = 10;

• Conditions are statements about the possible condition of the system that facts are matched against. Conditions are joined using AND, OR, etc. to create complex nodes. The “if” in an “if-then” statement.

• shirts.quantity < 15;

• Actions define possible out comes of a rule and are custom to the rules engine implementation. The “then” in an “if then statement.”

• ...then create an order for more shirts

• Rules combine facts, conditions and actions and can sometimes be nested

• using <facts> as input, if <conditions> then <actions>

Page 17: Obey The Rules: Implementing a Rules Engine in Flex

Rules Engine Anatomy: t-shirt inventory

Facts

Rules

Conditions

Actions

shirts.quantity = 10;

if ((shirts.quantity < 15)

create an order

Page 18: Obey The Rules: Implementing a Rules Engine in Flex

Rules Engine Anatomy: clown alarm system

Facts

Rules

Conditions

Actions

clowns.quantity = 10;

if ((clowns.quantity > 5)

OR

(clowns.haveKnives)

call Axe Cop

http://www.axecop.com

Page 19: Obey The Rules: Implementing a Rules Engine in Flex

Examples!

Page 20: Obey The Rules: Implementing a Rules Engine in Flex

Real world use case 1FormBuilderUI: AS3 rules engine under the hood

A simple AS3-based rules engine to demonstrate the power and ability of client-side rules engines. Uses dynamic object creation and rules parsing.

Engine Type: ProductionAlgorithm: Basic

Page 21: Obey The Rules: Implementing a Rules Engine in Flex
Page 22: Obey The Rules: Implementing a Rules Engine in Flex
Page 23: Obey The Rules: Implementing a Rules Engine in Flex

The Stack...

Page 24: Obey The Rules: Implementing a Rules Engine in Flex

The Rules...

<rule id="isFemale"><statement><![CDATA[ @info.sex equalTo 'Female' ]]></statement><actions>

<visibleAction questionIDs="areYouPregnant"/></actions>

</rule>

<rule id="isTeenager"><statement><![CDATA[ @info.age greaterThanOrEqualTo '13' AND

@info.age lessThan '18' ]]></statement><actions></actions>

</rule>

<rule id="isTeenageGirl"><statement><![CDATA[ $isTeenager AND $isFemale ]]></statement><actions>

<urlAction url="http://www.seventeen.com" /></actions>

</rule>

Page 25: Obey The Rules: Implementing a Rules Engine in Flex

Regular Expressions

public static var andOrTrueFalsePattern:RegExp = /AND|OR|true|false/gi;

public static var ruleTokenPattern:RegExp = /\$([a-zA-Z0-9_]+)/g;

public static var propertyTokenPattern:RegExp = /\@([a-zA-Z0-9_.]+)/g;

public static var nonSpaceGroups:RegExp = /([\$\@a-zA-Z0-9_.'"]+)([^ \n\r])/gi;

public static var quotesPattern:RegExp = /'|"/gi;

Page 26: Obey The Rules: Implementing a Rules Engine in Flex

Pattern matching a rule...

Page 27: Obey The Rules: Implementing a Rules Engine in Flex

Boolean parsing using short circuit

var matches:Array = [true, "AND", false, "AND", true, "OR" true];var operator:String; var nextValue:Boolean;var overallValue:Boolean = matches[0];

var i:int = 1;while (i < matches.length - 1) {

operator=matches[i];nextValue=StringUtil.stringToBoolean(matches[i + 1]);

if (isAndOperator(operator)) {overallValue=(overallValue && nextValue);if (overallValue == false)

return false;} else if (isOrOperator(operator)) {

overallValue=(overallValue || nextValue);if (overallValue == true)

return true;}i = i + 2;

}

“...the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression...”

Page 28: Obey The Rules: Implementing a Rules Engine in Flex

Hamcrest API - Matchers:

public static const EQUAL_TO:String = "equalTo";

public static const NOT_EQUAL_TO:String = "notEqualTo";

public static const LESS_THAN:String = "lessThan";

public static const LESS_THAN_OR_EQUAL_TO:String = "lessThanOrEqualTo";

public static const GREATER_THAN:String = "greaterThan";

public static const GREATER_THAN_OR_EQUAL_TO:String = "greaterThanOrEqualTo";

public static const CONTAINS:String = "contains";

Page 29: Obey The Rules: Implementing a Rules Engine in Flex

Hamcrest API: Get your facts straight!

public static function evaluateCondition(target:*, operator:String, source:*):Boolean {

try {switch (operator) {

case Matchers.EQUAL_TO:assertThat(target, equalTo(source));break;

case Matchers.NOT_EQUAL_TO:assertThat(target, not(equalTo(source)));break;

case Matchers.LESS_THAN:assertThat(Number(target), lessThan(Number(source)));break;

default:throw new RuleError("No matcher found for this operator!”);

}} catch (e:Error) {

if (e.errorID != RuleError.ILLEGAL_OPERATOR_ERROR) {value=false;

} else {_logger.error(e.message, e.errorID);

}}

Page 30: Obey The Rules: Implementing a Rules Engine in Flex

Type of Rules engines

There are several types of rules engines. For the most part they differ in the manner to which the Rules are scheduled for execution.

Page 31: Obey The Rules: Implementing a Rules Engine in Flex

• Used to represent behaviors of the type IF condition THEN action.

• "Should this customer be allowed a mortgage?"

• This question can be answered by executing rules of the form "IF some-condition THEN allow-customer-a-mortgage".

• production rule engines execute when a user or application invokes them - facts are explicitly passed in. Often a queue of facts is processed at once.

Engine types: production(inference)

Page 32: Obey The Rules: Implementing a Rules Engine in Flex

Engine types: reactive

• Also known as Event Condition Action (ECA) rules engines

• detect and react to incoming events and then process event patterns.

• A reactive rule could be used to alert a user when they have reached a negative balance in their bank account

• reactive engines react automatically when events occur.

• some engines have production and reactive capabilities

Page 33: Obey The Rules: Implementing a Rules Engine in Flex

The core of the rules engine is the algorithm used to process the rules.

We will discuss Basic (naive) and Rete processing algorithms.

Rule Processing Algorithms

Page 34: Obey The Rules: Implementing a Rules Engine in Flex

Basic Algorithm

• The basic or “naive” algorithm runs each new fact through the list of conditions and processes it appropriately.

• Less memory is required than Rete, but performance can be far worse

• Ideally used when you have a smaller set of rules to execute

• This is the algorithm you will most likely “wander” into if you are unfamiliar with rules systems or similar problems (pattern matching, for example

Page 35: Obey The Rules: Implementing a Rules Engine in Flex

Basic Algorithm

Fact

condition A

Action

Fact

cB cC cD

ANDOR

Fact

Optimizations can give priority to certain

conditions, wait to process until all facts are run

through conditions, etc.

Page 36: Obey The Rules: Implementing a Rules Engine in Flex

Rete Algorithm

• more complex implementation than basic.

• will take more time to implement initially

• performs with much greater efficiency

• save future optimization

Page 37: Obey The Rules: Implementing a Rules Engine in Flex

Rete Algorithm

• divides rules up into pieces

• scatters the pieces along a logical chain

• traverses the chain when new facts are added to the system

• joins operation nodes to produce outcomes

Page 38: Obey The Rules: Implementing a Rules Engine in Flex

Rete Algorithm

• is FAST - trades memory for performance

• stores rules in a network/tree structure (the “rete”)

• saves state at each node in the rete

• re-evaluates appropriate branches when new facts come in

• is what many other production rules engines are based on:

• Drools, Jess, JBoss Rete

Page 39: Obey The Rules: Implementing a Rules Engine in Flex

Rete Algorithm

Fact1

condition A

Action

Fact3

cB cC cD

AND

OR

clowns.quantity = 10;

if ((clowns.quantity > 5)

AND condition B

AND (condition C OR D))

call Axe Cop

Fact2

Page 40: Obey The Rules: Implementing a Rules Engine in Flex

Real world use case 2:Herff Jones Order Manager

EffectiveUI was hired by Herff Jones to rebuild their sales. rep. CMS for managing student class ring, cap and gown and fine papers orders. Herff Jones leads this market. Their sales reps. must have an optimized workflow for entering in large numbers of complex orders quickly and accurately.

Engine Type: ProductionAlgorithm: Rete

Page 41: Obey The Rules: Implementing a Rules Engine in Flex
Page 42: Obey The Rules: Implementing a Rules Engine in Flex
Page 43: Obey The Rules: Implementing a Rules Engine in Flex

Technical Challenges

• Class Rings have an “unruly” number of options for customization. The options include name, engraving, size, color, metal, stone, ect.

• Business rules define what options available based on pre-condtions (i.e. if you choose a stone, then other options are available specific to the stone)

• The sales rep collects printed order forms and must enter the ring orders into the Order Manager Flex application. This process demands efficiency and accuracy

• Potentially hundreds of thousands of combinations for ring options.

• Currently these were in a database on a server in each rep office. The rules apply across the entire business so it makes sense to define them globally

Page 44: Obey The Rules: Implementing a Rules Engine in Flex

Core Components

• Rule Processing engine for defining user pathways in the ring order form

• Due to the nature and quantity of business rules, the Rete algorithm was used to implement the engine

• The ring pricing is also determined based on external business rules using the same engine

• Certain rules are shared across other parent rules and should not be evaluated more than once in the same execution cycle. We use “Macros” in this case.

Page 45: Obey The Rules: Implementing a Rules Engine in Flex

Core UI

• The ring order form consists of a standard form with a set of “base” options

• As soon as the base options are selected then the processor is enabled to run each time a form value changes.

• The business rules are passed targets which represent the state of the form and evaluate on that state.

• If a rule evaluates to true it will generally add additonal value options to the target object.

• If a rule evaluates to false then the options are not added

Page 46: Obey The Rules: Implementing a Rules Engine in Flex

<!-- Rule definition --><rule> <getValue key="Metal Quality"><containsString value="Gold"/></getValue> <addValueOption key="Metal Finish" value="Gold-on-Gold" meta="code:2"/></rule>

Rule XML Sample

Page 47: Obey The Rules: Implementing a Rules Engine in Flex

Macro XML Sample: pricing a stone

<!-- Macro definition --><defineMacro name="priceStone">

<rule><allOf>

<getValue key="$stoneKey"><equalTo value="$stoneValue"/></getValue><getValue key="$stoneSizeKey"><equalTo value="$stoneSizeValue"/></getValue>

</allOf><addPrice label="$stoneKey: $stoneValue" amount="$amount"/>

</rule></defineMacro>

<!-- Macro implementation --><priceStone stoneKey="Royal Stone" stoneValue="Birthstones - Alexandrite (Jun)" stoneSizeKey="Royal Stone Size" stoneSizeValue="12 Point" amount="4208"/>

Page 48: Obey The Rules: Implementing a Rules Engine in Flex

Real world use case 3:A Statewide Agency Government Benefits Application (GBA)

EffectiveUI was hired to help with revamping the user experience of an existing forms-driven web application that allows users to apply for state-assisted benefits.

Engine Type: ReactiveAlgorithm: Modified Rete

Page 49: Obey The Rules: Implementing a Rules Engine in Flex

GBAOverview

GBA allows households to apply for state wide benefits including welfare, food stamps, healthcare, income assistance and more.

QuickTime™ and aAnimation decompressor

are needed to see this picture.

Page 50: Obey The Rules: Implementing a Rules Engine in Flex

Functionality

• The GBA client should be able to display questions based on previous answers provided in the form.

• The GBA client should be able to update properties on the data model based on answers provided by the user.

• The GBA client should be able to perform other actions such in response to a user asking certain questions.

Page 51: Obey The Rules: Implementing a Rules Engine in Flex

Technical Challenges

• The State Agency does not allow redeploying SWF files without extensive review and approval cycles

• When an GBA application is submitted to the server it must go through a complex series of server logic and eventually be routed to multiple disparate legacy systems.

• The client must react to user input immediately to provide the proper user experience. We cannot make server calls to process form input through rules.

Page 52: Obey The Rules: Implementing a Rules Engine in Flex

Core Components

• Rules facts and actions that are declared in external XML files

• Parsing logic to convert that XML into objects used by the processor

• A data model the can be monitored by the processor. All objects were [Bindable]

Page 53: Obey The Rules: Implementing a Rules Engine in Flex

...Core Components

• An observer to handle listening for property changes on the data model. We used Flex data binding to monitor all the subject data.

• A processor to execute any rule that contains the subject data that has changed.

• A command interface and message model to perform custom actions in the software application.

Page 54: Obey The Rules: Implementing a Rules Engine in Flex

GBA Rules engine architecture

Fact(change event)

Conditions

Actions

User Questions

Data ModelB

indin

g!

Bin

din

g!

Binding!

Page 55: Obey The Rules: Implementing a Rules Engine in Flex

Core UI

• Dynamically define all forms and their fields (questions) in xml

• Allow customization of form elements to include validation, formatting

• Option data with sorting and filtering for inclusive questions

• Derived Properties (age derived from birthdate)

Page 56: Obey The Rules: Implementing a Rules Engine in Flex

<question id="362"controlType="ComboBox"inlineHelp="Does anyone receive money from elsewhere?"label="Other Employment"optionsID="R00013"target="Household.Income.OtherIncome"/>

Question XML

Page 57: Obey The Rules: Implementing a Rules Engine in Flex

<condition id="hasCurrentEmployment" targetProperty="Individual.HasCurrentEmployment" operator="equalTo" sourceValue="true"/>

<condition id="hasPastEmployment" targetProperty="Individual.HasPastEmployment" operator="equalTo" sourceValue="true"/>

Condition XML

Page 58: Obey The Rules: Implementing a Rules Engine in Flex

<rule id="doesAnyoneHasOtherEmployment"><statement>$hasOtherEmployment</statement><actions>

<visibleAction questionGroupIDs="income_other"/></actions>

</rule>

<rule id="NoEmployment"><statement>$IsOnStrike OR ($NoFutureEmployment AND

$NoCurrentEmployment AND $NoPastEmployment AND $NoOtherIncome)</statement>

<actions><visibleAction questionIDs="364"/>

</actions></rule>

Rule XML

Page 59: Obey The Rules: Implementing a Rules Engine in Flex

Data Abstraction

Page 60: Obey The Rules: Implementing a Rules Engine in Flex

Dynamic Binding using ObjectProxy

• The Flex client needed to support data binding, however the data schema was based on an external XSD.

• So we chose to implement an XMLProxy class by extending ObjectProxy which supports data binding on dynamic objects.

• We then implemented a serializer that would convert the raw XML into XMLProxy objects

• This allows the data model, or the rules to change without having to redeploy a SWF.

• The ObjectProxy class is very expensive and takes up mucho memory

Page 61: Obey The Rules: Implementing a Rules Engine in Flex

What next?

• Open source Rete and modified basic rules library and form builder library

• Zachary Pinter, other contributors?

Page 62: Obey The Rules: Implementing a Rules Engine in Flex

Thanks for obeying.

Drew McLeantwitter: [email protected]

RJ Owentwitter: [email protected]