Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Obey The Rules: Implementing a Rules Engine in Flex


Published on

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.

Published in: Technology
  • A very insightful presentation on what a rule engine is and how it may be implemented using AS3. I might embark on this mission soon, and if I do, this presentation might serve as the starting point. Thanks much for taking time to make and share it with us.
    Are you sure you want to  Yes  No
    Your message goes here

Obey The Rules: Implementing a Rules Engine in Flex

  1. 1. Obey the Rules! <ul><li>Understand business rules processing theory </li></ul><ul><li>Review real world case studies on client side rules processing. </li></ul><ul><li>Walk through a simple a client-side rules processing engine written in Flex 3.0 </li></ul>
  2. 2. What is a rules engine?
  3. 3. Rules engines <ul><li>are mechanisms for executing business rules in a runtime production environment. </li></ul><ul><li>separate business rules from application logic (encapsulation!) </li></ul><ul><li>are often deployed on a web application server. </li></ul><ul><li>are packaged as components with the ability to create, define, classify and manage business rules. </li></ul>
  4. 4. <ul><ul><li>are formalized specifications of business processes </li></ul></ul><ul><ul><li>are statements that define or constrain some aspect an organization </li></ul></ul>Business rules Business process : keep stores well stocked. Business rule : If the number of shirts in a store gets below 15, order more.
  5. 5. <ul><li>Business rules change more frequently than the rest of the application code. </li></ul><ul><li>Business rules require input and management by an organization (human). </li></ul><ul><li>Business rules can be completely externalized from the application (code) or carefully organized </li></ul><ul><li>This is accomplished through good application architecture, which may or may not include a rules engine </li></ul>Keep ‘em Separated
  6. 7. Why use a rules engine in your application? <ul><li>Lower the cost in modifying business logic </li></ul><ul><li>Shorten development time and maintenance time </li></ul><ul><li>Rules are externalized so can easily shared across multiple applications </li></ul><ul><li>Changes can be made faster and with less risk </li></ul><ul><li>Increase productivity and flexibility in your business </li></ul><ul><li>Lots of business-specific code or some well organized XML rules? </li></ul>
  7. 8. How are rules defined and implemented?
  8. 9. Typical workflow from business to technology The organization defines the business processes.
  9. 10. Typical workflow from business to technology A business analyst translates business practices into business rule statements, constraints and actions.
  10. 11. 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
  11. 12. Typical workflow from business to technology The organization changes some business processes.
  12. 13. 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.
  13. 14. Why use a client-side rules engine in your Flex RIA? <ul><li>Provide an experience that is more contextual and unique to the user </li></ul><ul><li>Remove server dependencies for processing business rules logic. </li></ul><ul><li>Do not have to recompile your .SWF when business logic changes. </li></ul><ul><li>Quicker response to user input that triggers rules. </li></ul>
  14. 15. How do rules engines work?
  15. 16. Rules Engine Anatomy <ul><li>Facts are input to the engine; statements about the system. Often key/value pairs. </li></ul><ul><ul><li>shirts.quantity = 10; </li></ul></ul><ul><li>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. </li></ul><ul><ul><li>shirts.quantity < 15; </li></ul></ul><ul><li>Actions define possible out comes of a rule and are custom to the rules engine implementation. The “then” in an “if then statement.” </li></ul><ul><ul><li>...then create an order for more shirts </li></ul></ul><ul><li>Rules combine facts, conditions and actions and can sometimes be nested </li></ul><ul><ul><li>using <facts> as input, if <conditions> then <actions> </li></ul></ul>
  16. 17. Rules Engine Anatomy: t-shirt inventory Facts Rules Conditions Actions <ul><ul><li>shirts.quantity = 10; </li></ul></ul><ul><ul><li>if ((shirts.quantity < 15) </li></ul></ul><ul><ul><li>create an order </li></ul></ul>
  17. 18. Rules Engine Anatomy: clown alarm system Facts Rules Conditions Actions <ul><ul><li>clowns.quantity = 10; </li></ul></ul><ul><ul><li>if ((clowns.quantity > 5) </li></ul></ul><ul><ul><li>OR </li></ul></ul><ul><ul><li>(clowns.haveKnives) </li></ul></ul><ul><ul><li>call Axe Cop </li></ul></ul>
  18. 19. Examples!
  19. 20. Real world use case 1 FormBuilderUI: AS3 rules engine under the hood AS3 rules engine under the hood <ul><li>A simple AS3-based rules engine to demonstrate the power and ability of client-side rules engines. Uses dynamic object creation and rules parsing. </li></ul><ul><li>Engine Type: Production </li></ul><ul><li>Algorithm: Basic </li></ul>
  20. 23. The Stack...
  21. 24. The Rules... < rule id = &quot;isFemale&quot; > < statement ><![CDATA[ equalTo 'Female' ]]></ statement > < actions > < visibleAction questionIDs = &quot;areYouPregnant&quot; /> </ actions > </ rule > < rule id = &quot;isTeenager&quot; > < statement ><![CDATA[ @info.age greaterThanOrEqualTo '13' AND @info.age lessThan '18' ]]></ statement > < actions > </ actions > </ rule > < rule id = &quot;isTeenageGirl&quot; > < statement ><![CDATA[ $isTeenager AND $isFemale ]]></ statement > < actions > < urlAction url = &quot; &quot; /> </ actions > </ rule >
  22. 25. 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_.'&quot;]+)([^ ])/ gi; public static var quotesPattern:RegExp = /'|&quot;/ gi;
  23. 26. Pattern matching a rule...
  24. 27. Boolean parsing using short circuit <ul><li>“ ...the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression...” </li></ul>var matches:Array = [ true , &quot;AND&quot; , false , &quot;AND&quot; , true , &quot;OR&quot; 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; }
  25. 28. Hamcrest API - Matchers: public static const EQUAL_TO:String = &quot;equalTo&quot; ; public static const NOT_EQUAL_TO:String = &quot;notEqualTo&quot; ; public static const LESS_THAN:String = &quot;lessThan&quot; ; public static const LESS_THAN_OR_EQUAL_TO:String = &quot;lessThanOrEqualTo&quot; ; public static const GREATER_THAN:String = &quot;greaterThan&quot; ; public static const GREATER_THAN_OR_EQUAL_TO:String = &quot;greaterThanOrEqualTo&quot; ; public static const CONTAINS:String = &quot;contains&quot; ;
  26. 29. 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( &quot;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); } }
  27. 30. Type of Rules engines <ul><li>There are several types of rules engines. For the most part they differ in the manner to which the Rules are scheduled for execution. </li></ul>
  28. 31. <ul><li>Used to represent behaviors of the type IF condition THEN action. </li></ul><ul><li>&quot;Should this customer be allowed a mortgage?&quot; </li></ul><ul><li>This question can be answered by executing rules of the form &quot; IF some-condition THEN allow-customer-a-mortgage&quot;. </li></ul><ul><li>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. </li></ul>Engine types: production(inference)
  29. 32. Engine types: reactive <ul><li>Also known as Event Condition Action (ECA) rules engines </li></ul><ul><li>detect and react to incoming events and then process event patterns. </li></ul><ul><li>A reactive rule could be used to alert a user when they have reached a negative balance in their bank account </li></ul><ul><li>reactive engines react automatically when events occur. </li></ul><ul><li>some engines have production and reactive capabilities </li></ul>
  30. 33. <ul><li>The core of the rules engine is the algorithm used to process the rules. </li></ul><ul><li>We will discuss Basic (naive) and Rete processing algorithms. </li></ul>Rule Processing Algorithms
  31. 34. Basic Algorithm <ul><li>The basic or “naive” algorithm runs each new fact through the list of conditions and processes it appropriately. </li></ul><ul><li>Less memory is required than Rete, but performance can be far worse </li></ul><ul><li>Ideally used when you have a smaller set of rules to execute </li></ul><ul><li>This is the algorithm you will most likely “wander” into if you are unfamiliar with rules systems or similar problems (pattern matching, for example </li></ul>
  32. 35. Basic Algorithm Fact condition A Action Fact cB cC cD AND OR Fact Optimizations can give priority to certain conditions, wait to process until all facts are run through conditions, etc.
  33. 36. Rete Algorithm <ul><li>more complex implementation than basic. </li></ul><ul><li>will take more time to implement initially </li></ul><ul><li>performs with much greater efficiency </li></ul><ul><li>save future optimization </li></ul>
  34. 37. Rete Algorithm <ul><li>divides rules up into pieces </li></ul><ul><li>scatters the pieces along a logical chain </li></ul><ul><li>traverses the chain when new facts are added to the system </li></ul><ul><li>joins operation nodes to produce outcomes </li></ul>
  35. 38. Rete Algorithm <ul><li>is FAST - trades memory for performance </li></ul><ul><li>stores rules in a network/tree structure (the “rete”) </li></ul><ul><li>saves state at each node in the rete </li></ul><ul><li>re-evaluates appropriate branches when new facts come in </li></ul><ul><li>is what many other production rules engines are based on: </li></ul><ul><ul><li>Drools, Jess, JBoss Rete </li></ul></ul>
  36. 39. Rete Algorithm Fact1 condition A Action Fact3 cB cC cD AND OR <ul><ul><li>clowns.quantity = 10; </li></ul></ul><ul><ul><li>if ((clowns.quantity > 5) </li></ul></ul><ul><ul><li>AND condition B </li></ul></ul><ul><ul><li>AND (condition C OR D)) </li></ul></ul><ul><ul><li>call Axe Cop </li></ul></ul>Fact2
  37. 40. Real world use case 2: Herff Jones Order Manager Herff Jones Order Manager <ul><li>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. </li></ul><ul><li>Engine Type: Production </li></ul><ul><li>Algorithm: Rete </li></ul>
  38. 43. Technical Challenges <ul><li>Class Rings have an “unruly” number of options for customization. The options include name, engraving, size, color, metal, stone, ect. </li></ul><ul><li>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) </li></ul><ul><li>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 </li></ul><ul><li>Potentially hundreds of thousands of combinations for ring options. </li></ul><ul><li>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 </li></ul>
  39. 44. Core Components <ul><li>Rule Processing engine for defining user pathways in the ring order form </li></ul><ul><li>Due to the nature and quantity of business rules, the Rete algorithm was used to implement the engine </li></ul><ul><li>The ring pricing is also determined based on external business rules using the same engine </li></ul><ul><li>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. </li></ul>
  40. 45. Core UI <ul><li>The ring order form consists of a standard form with a set of “base” options </li></ul><ul><li>As soon as the base options are selected then the processor is enabled to run each time a form value changes. </li></ul><ul><li>The business rules are passed targets which represent the state of the form and evaluate on that state. </li></ul><ul><li>If a rule evaluates to true it will generally add additonal value options to the target object. </li></ul><ul><li>If a rule evaluates to false then the options are not added </li></ul>
  41. 46. Rule XML Sample <!-- Rule definition --> < rule > < getValue key = &quot;Metal Quality&quot; >< containsString value = &quot;Gold&quot; /></ getValue > < addValueOption key = &quot;Metal Finish&quot; value = &quot;Gold-on-Gold&quot; meta = &quot;code:2&quot; /> </ rule >
  42. 47. Macro XML Sample: pricing a stone <!-- Macro definition --> < defineMacro name = &quot;priceStone&quot; > < rule > < allOf > < getValue key = &quot;$stoneKey&quot; >< equalTo value = &quot;$stoneValue&quot; /></ getValue > < getValue key = &quot;$stoneSizeKey&quot; >< equalTo value = &quot;$stoneSizeValue&quot; /></ getValue > </ allOf > < addPrice label = &quot;$stoneKey: $stoneValue&quot; amount = &quot;$amount&quot; /> </ rule > </ defineMacro > <!-- Macro implementation --> < priceStone stoneKey = &quot;Royal Stone&quot; stoneValue = &quot;Birthstones - Alexandrite (Jun)&quot; stoneSizeKey = &quot;Royal Stone Size&quot; stoneSizeValue = &quot;12 Point&quot; amount = &quot;4208&quot; />
  43. 48. Real world use case 3: A Statewide Agency Government Benefits Application (GBA) Government Benefits Application (GBA) Government Benefits Application (GBA) <ul><li>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. </li></ul><ul><li>Engine Type: Reactive </li></ul><ul><li>Algorithm: Modified Rete </li></ul>
  44. 49. GBA Overview Overview <ul><li>GBA allows households to apply for state wide benefits including welfare, food stamps, healthcare, income assistance and more. </li></ul>
  45. 50. Functionality <ul><li>The GBA client should be able to display questions based on previous answers provided in the form. </li></ul><ul><li>The GBA client should be able to update properties on the data model based on answers provided by the user. </li></ul><ul><li>The GBA client should be able to perform other actions such in response to a user asking certain questions. </li></ul>
  46. 51. Technical Challenges <ul><li>The State Agency does not allow redeploying SWF files without extensive review and approval cycles </li></ul><ul><li>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. </li></ul><ul><li>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. </li></ul>
  47. 52. Core Components <ul><li>Rules facts and actions that are declared in external XML files </li></ul><ul><li>Parsing logic to convert that XML into objects used by the processor </li></ul><ul><li>A data model the can be monitored by the processor. All objects were [Bindable] </li></ul>
  48. 53. ...Core Components <ul><li>An observer to handle listening for property changes on the data model. We used Flex data binding to monitor all the subject data. </li></ul><ul><li>A processor to execute any rule that contains the subject data that has changed. </li></ul><ul><li>A command interface and message model to perform custom actions in the software application. </li></ul>
  49. 54. GBA Rules engine architecture Fact (change event) Conditions Actions User Questions Data Model Binding! Binding! Binding!
  50. 55. Core UI <ul><li>Dynamically define all forms and their fields (questions) in xml </li></ul><ul><li>Allow customization of form elements to include validation, formatting </li></ul><ul><li>Option data with sorting and filtering for inclusive questions </li></ul><ul><li>Derived Properties (age derived from birthdate) </li></ul>
  51. 56. Question XML < question id = &quot;362&quot; controlType = &quot;ComboBox&quot; inlineHelp = &quot;Does anyone receive money from elsewhere?&quot; label = &quot;Other Employment&quot; optionsID = &quot;R00013&quot; target = &quot;Household.Income.OtherIncome&quot; />
  52. 57. Condition XML <ul><li>< condition id = &quot;hasCurrentEmployment&quot; </li></ul><ul><ul><ul><ul><li>targetProperty = &quot;Individual.HasCurrentEmployment&quot; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>operator = &quot;equalTo&quot; sourceValue = &quot;true&quot; /> </li></ul></ul></ul></ul><ul><li>< condition id = &quot;hasPastEmployment&quot; </li></ul><ul><ul><ul><ul><li>targetProperty = &quot;Individual.HasPastEmployment&quot; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>operator = &quot;equalTo&quot; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>sourceValue = &quot;true&quot; /> </li></ul></ul></ul></ul>
  53. 58. Rule XML < rule id = &quot;doesAnyoneHasOtherEmployment&quot; > < statement > $hasOtherEmployment </ statement > < actions > < visibleAction questionGroupIDs = &quot;income_other&quot; /> </ actions > </ rule > < rule id = &quot;NoEmployment&quot; > < statement > $IsOnStrike OR ($NoFutureEmployment AND $NoCurrentEmployment AND $NoPastEmployment AND $NoOtherIncome) </ statement > < actions > < visibleAction questionIDs = &quot;364&quot; /> </ actions > </ rule >
  54. 59. Data Abstraction
  55. 60. Dynamic Binding using ObjectProxy <ul><li>The Flex client needed to support data binding, however the data schema was based on an external XSD. </li></ul><ul><li>So we chose to implement an XMLProxy class by extending ObjectProxy which supports data binding on dynamic objects. </li></ul><ul><li>We then implemented a serializer that would convert the raw XML into XMLProxy objects </li></ul><ul><li>This allows the data model, or the rules to change without having to redeploy a SWF. </li></ul><ul><li>The ObjectProxy class is very expensive and takes up mucho memory </li></ul>
  56. 61. What next? <ul><li>Open source Rete and modified basic rules library and form builder library </li></ul><ul><ul><li>Zachary Pinter, other contributors? </li></ul></ul>
  57. 62. Forward Chaining (modus ponens) <ul><li>If P, then Q </li></ul><ul><li>P . </li></ul><ul><li>Therefore , Q . </li></ul><ul><li>If today is Wednesday , then I will drink beer . </li></ul><ul><li>Today is Wednesday . </li></ul><ul><li>Therefore , I will drink beer . </li></ul>
  58. 63. Forward Chaining <ul><li>The argument form has two premises. </li></ul><ul><li>The first premise is the &quot;if–then&quot; or conditional claim, namely that P implies Q. </li></ul><ul><li>The second premise is that P is true. </li></ul><ul><li>From these two premises it can be logically concluded that Q must be true as well </li></ul><ul><li>Forward chaining is derived from the philosophical concept known as modus ponens . </li></ul>
  59. 64. Forward Chaining: definition <ul><ul><li>The following example uses forward chaining to determine the color of X based on existing data about X. </li></ul></ul><ul><li>1. If X croaks and eats flies - Then X is a frog </li></ul><ul><li>2. If X chirps and sings - Then X is a canary </li></ul><ul><li>3. If X is a frog - Then X is green </li></ul><ul><li>4. If X is a canary - Then X is yellow </li></ul>
  60. 65. Thanks for obeying. Drew McLean twitter: TunnelVisionary [email_address] RJ Owen twitter: rjowen [email_address]