Welcome!

ColdFusion Authors: Maureen O'Gara, Hovhannes Avoyan, Yakov Fain, Pat Romanski, Liz McMillan

Related Topics: ColdFusion

ColdFusion: Article

Playing With(in) the Rules

The Rule Manager Façade

A Sample RuleManager Component
Due to publishing constraints I've simplified the sample RuleManager code quite considerably for this article. For example, the sample RuleManager doesn't provide any features for dynamically loading or unloading different criteria types or groups of criteria types - instead it merely examines a directory for CFCs and assumes each is a criteria type CFC. I've also eliminated debugging features, a considerable amount of i18n functionality for multilingual applications (which is no small challenge to implement with a RuleManager), simplified the provided criteria CFCs, and omitted nearly a dozen common criteria types. One feature I'm particularly sorry to omit is the ability for individual criteria CFCs to introspect the provided rule context to determine their own applicability to the context. Although I feel this is an important feature for the sake of encapsulation and extensibility, it would simply require too much space to include in this article.

Having trimmed the code for the RuleManager sample to a bare minimum, here are the absolutely necessary features of the façade (RuleManager.cfc) for this application to function:

  • Rule CRUD: Create/Read/Update/Delete methods for individual rules must modify the loaded ruleset XML (stored in memory as a property of the RuleManager.cfc object) and return or provide a means of accessing the text-representation of the current ruleset document for storage (which can be stored either in a file or in a database). Methods: getRuleNode, setRuleNode, ruleExists, deleteRule.
  • Criteria CRUD: Create/Read/Update/Delete methods for individual rule criteria. Although rules must be identified with a unique id such as a UUID, a criteria node within a rule may be identified by its position within the rule so long as the rule identifier is used when fetching the criteria node. Criteria create/update/delete methods must also return the text representation of the XML ruleset or provide a means of accessing its text-representation for storage (see above). Methods: getCriteriaNode, setCriteriaNode, getCriteriaForm, getCriteriaXML, getRuleCriteria, deleteCriteria.
  • Criteria Object Management: In order for the RuleManager to perform efficiently it must cache criteria-type CFCs in memory and use the cached CFCs for managing and interpreting individual criteria nodes. The façade (RuleManager.cfc) must also provide a list of the available criteria types. Methods: getCriteriaObject, getCriteriaQuery.
  • Test Rule: This is the singular feature for which all other features exist. Once a user has created their rules and assigned their criteria your application must have a means of identifying and testing the applicability of those rules to apply the various application features you want controlled by user-defined rules. Method: ruleApplies.
In addition to these features of the façade, a common interface is required for the different criteria-type CFCs, which will be managed by the façade. This is accomplished by designating a predefined set of methods (including arguments and return types) that all criteria-type CFCs must share. With these methods in place the façade can then reference any individual criteria-type without needing to know any of the internal mechanics of the criteria.
  • void getForm(node , context [, nodeData]): This function displays a form for the user to update any criteria of the specified type. Although it may seem strange or even contrary to popular OO "best practice" to display the form from within the CFC, this approach provides maximum encapsulation. The content being updated by this form exists solely for the purpose of being used by this CFC and nothing else, and including the form in this method ensures that no criteria CFC will be without a user interface, and it also ensures that the façade is kept ignorant of the internal mechanics of the individual criteria-type CFCs. Called within RuleManager.getCriteriaForm.

    string getXMLNode(nodeData): Once the criteria form is submitted it is necessary to return to the criteria-type CFC to determine the syntax for the criteria node before updating the ruleset XML document. Called within RuleManager.setCriteriaNode.

  • string describe(node , context): Because the façade must manage many different types of criteria it cannot contain any logic for describing the applied criteria and still maintain encapsulation. For this reason the describe method is required in each criteria-type CFC. Called within RuleManager.getRuleCriteria.
  • boolean test(node , context): Finally in order to determine the applicability of any given rule, the RuleManager façade must be able to rely on the criteria-type CFCs that created the individual criteria XML nodes to interpret those same XML nodes. Called within RuleManager.ruleApplies.
At this point you might notice that almost all of the criteria-type interface methods include an argument named "context." If you remember from the previous sections of the article, one of the assumptions in the RuleManager application is "All parameters used by criteria-type CFCs in the evaluation of a rule must be provided in the criteria XML node or by an external context (CFC)." By providing the context in the getForm method the criteria-type object is able to determine what properties will be available for testing later. These values are supplied to the getXMLNode method through the form-scope and so are not needed in this method. The context is necessary however when describing the criteria (just as the names of context-properties are provided to the getForm method) and to fetch the current value of selected context-properties when evaluating the applicability of individual criteria when testing the rule.

More Stories By Isaac Dealey

Isaac Dealey has worked with ColdFusion since 1997 (version 3) for clients from small businesses to large enterprises, including MCI and AT&T Wireless. He evangelizes ColdFusion as a volunteer member of Team Macromedia, is working toward becoming a technical instructor, and is available for speaking engagements.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.