then section of a rule (also known as the Right Hand Side or RHS) contains the actions that execute when the rule’s conditions are met. While the when section uses a specialized pattern-matching syntax, the then section contains plain Java code. This chapter explores how to write effective rule actions that implement your business logic.
Understanding Rule Actions
Rule actions serve several purposes:- Modify facts: Update the properties of matched facts
- Add or remove facts: Insert new facts or remove existing ones
- Execute business logic: Perform calculations or operations
- Trigger side effects: Call external services, log events, or send notifications
Working with Facts
Facts are the objects that rules operate on. The Drools rule engine maintains a working memory containing all facts, and rule actions can modify this memory.Modifying Facts
When you match a fact in thewhen section and need to update its properties, you can modify it directly:
customers.update($customer) call. This informs the rule engine that the fact has been modified, which can trigger other rules that depend on those properties. Always remember to update the data source after modifying a fact.
The modify Block
As an alternative to directly modifying properties and calling update(), you can use the modify block:
modify block automatically handles the update for you, which helps prevent errors where you might forget to call update(). It also clearly groups the changes being made to a single object.
Adding New Facts
To add a new fact to working memory, you create the object and add it to the appropriate data source:Removing Facts
Sometimes you need to remove facts from working memory when they’re no longer relevant:Logical Insertions
Drools supports the concept of logical insertions withaddLogical(). Facts added with this method are automatically removed when the conditions that led to their insertion are no longer true:
ShippingDiscount will be automatically removed from working memory.
Executing Business Logic
Rule actions often need to perform business logic beyond simple fact modifications.Calculations
You can perform calculations directly in the rule action:Method Calls
You can call methods on fact objects or utility classes:Conditional Logic
While you should strive to keep rule actions simple and declarative, sometimes you need conditional logic:Error Handling and Validation
Rule actions should handle errors gracefully and validate data to ensure robustness.Try-Catch Blocks
When calling external services or performing operations that might fail, use try-catch blocks:Input Validation
Even though constraints in thewhen section filter facts, it’s sometimes necessary to perform additional validation in the actions:
Logging and Debugging
Adding logging to rule actions can be invaluable for debugging and monitoring:System.out.
Advanced Action Techniques
Beyond the basics, there are several advanced techniques for rule actions.Asynchronous Actions
For actions that might take time to complete, consider making them asynchronous:External Services Integration
Rules often need to interact with external systems:Reusable Action Methods
For complex operations that are used in multiple rules, consider extracting them to helper methods:Best Practices for Rule Actions
To keep your rule system maintainable and efficient, follow these best practices:1. Keep Actions Simple and Focused
Each rule should perform a single, well-defined action. If a rule needs to perform multiple operations, consider whether it should be split into multiple rules. Benefits of simple actions include:- Easier to understand: The purpose of the rule is clear
- Easier to maintain: Changes to one aspect don’t affect others
- Better performance: Rules can be optimized more effectively
- Better reuse: Simple actions are more likely to be reusable
2. Use Declarative Style When Possible
Prefer a declarative style (stating what should happen) over imperative style (stating how it should happen) where possible:3. Always Update Facts After Modification
Remember to callupdate() after modifying facts or use the modify block:
4. Be Careful with Side Effects
Rule actions often have side effects like logging, sending emails, or updating databases. Handle these carefully:- Idempotence: Can the action safely be performed multiple times?
- Transactions: Do you need transaction management for database operations?
- Error handling: What happens if the side effect fails?
- Asynchronous operations: Should the side effect be performed asynchronously?
5. Use Helper Methods for Complex Logic
Extract complex logic into helper methods:6. Handle Errors Gracefully
Always include error handling in rule actions that interact with external systems:7. Avoid Infinite Rule Activations
Be careful not to create infinite loops. This can happen when a rule’s actions trigger the same rule again:no-loop or condition constraints to prevent this:
Real-World Examples
Let’s examine some comprehensive examples of rule actions in real-world scenarios.E-commerce Order Processing
Loan Application Approval
- Setting multiple properties on the application
- Using helper methods for calculations
- Interacting with external services
- Error handling
- Creating related objects
- Logging
Insurance Claim Processing
Performance Considerations
Rule actions can impact the performance of your rule system. Consider these tips:1. Minimize Working Memory Modifications
Every time you update a fact, the rule engine must reevaluate rules that might be affected. Minimize unnecessary updates:2. Use Property Reactivity
Drools supports property reactivity, which means it only reevaluates rules that depend on the specific properties you’ve changed. Make sure your fact classes properly define getter methods for all properties used in rules.3. Avoid Expensive Operations in Rule Actions
Expensive operations like database queries, web service calls, or complex calculations should be minimized or optimized:- Caching: Cache results of expensive operations
- Batching: Group operations for batch processing
- Asynchronous processing: Move expensive operations to background threads
- Precomputation: Calculate values in advance when possible
Summary
Thethen section of a rule is where your business logic comes to life. While the condition section determines when a rule should fire, the action section determines what happens when it does.
Effective rule actions should be:
- Clear and focused: Each rule should perform a specific, well-defined action
- Declarative: State what should happen, not how it should happen
- Robust: Include proper error handling and validation
- Efficient: Minimize unnecessary working memory modifications
- Maintainable: Use helper methods and consistent patterns