A Business Rules Engine should not replace Z-Tables…
Carsten Ziegler recently wrote a great blog post entitled How to Kill Custom Code and Z-Tables in which he shared how he was able to use a business rules engine (SAP DSM) to implement a simple business rule that would otherwise have needed many lines of ABAP code and many Z-tables. At first glance, it might seem that the title of my blog post contradicts Carsten’s claim but I encourage you to read on to see why this is not the case.
My blog post title suggests that you can’t simply replace Z-tables in your application with a business rule engine, but isn’t that what Carsten said he did? Maybe. The key thing to note is that Carsten’s post didn’t just talk about reducing Z-tables but custom code too. This is a very important difference as it proposes that a business rule is not just a bunch of data records in a table but that a business rule also contains its own logic along with the data. I hope to explain this differentiation more clearly later but first let’s pull apart at a simple business rule to see what I mean about rules containing logic.
Dissection of a simple rule
Imagine you had a business rule that says that certain types of purchase requisitions can be auto-approved and let’s assume that every purchase req that doesn’t meet this rule needs to go through the manual approval process. In pseudo-code the business rule part might look something like:
IF purchase req type EQUALS ‘Z1’ OR ‘Z2’ OR … THEN
Purchase req can be auto-approved
Purchase req cannot be auto-approved
Notice the conditional logic? I’ve highlighted the conditional keywords, just in case.
If you tried to implement this rule using ABAP and a Z-table you might do something like this:
FROM Z_PREQ_AUTO _APPROVAL
WHERE preq_type = current_preq_type.
IF sy-subrc = 0.
Purchase req can be auto-approved
Purchase req cannot be auto-approved
Notice that the rule data is contained in the Z-table and the rule logic is wholly contained in ABAP? If you wanted to implement some clever “wild card” functionality within the table data then you would have to suck all the data out of the Z-table but the logic processing would still be in ABAP.
However, if you implemented this same rule in BRFplus you would pass the purchase req type to your BRFplus function and it would return a result saying whether the purchase req can be auto-approved. You could use a value range or decision table to implement the rule but, in effect, the whole of the previous ABAP code snippet (conditional logic plus the purchase req types data) can be replaced by a single call to a BRFPlus function.
If you’ve used a business rules engine before then you might think that this is all pretty obvious… so why am I labouring the point? It’s because I often encounter developers, particularly those who haven’t had too much experience with business rules, who try to use a business rules engine as a simple datastore rather than as a business rules engine. This behaviour often leads to the developer asking questions like “How do I extract all the data, including the condition columns, from a decision table into my code?”. This type of question suggests that the developer is trying to implement rule logic in their code rather than in the rules engine.
Why is this bad?
I have a couple of reasons:
Firstly, one of the benefits of a business rules repository/engine is that it can be used to abstract your business rules from your code so that they can be maintained independently. Once the definition of the rule is fixed and the interface between your code and the rules engine has been defined (in the BRFplus function) then changes in the implementation of the business rule should not necessarily affect the code and vice versa. You should be able to replace your decision table with a value range or a decision tree without needing to change a single line of code. But if your code assumes that a business rule will be implemented in a certain way inside the rules engine then you’ve broken the abstraction and have tightly coupled your code and rule implementations, cancelling out the benefits of abstraction.
The second, slightly less technical reason is that if you keep putting business rule logic into your code then you’re defeating the whole purpose of having a rules repository. A centralised rules repository allows you to have one place to go to find and analyse all of your business rules. This centralisation of rules can benefit developers, functional consultants and key users alike but if some rules logic is left in code then you will have split your rules into multiple “repositories” and some of those repositories will only be accessible to developers.
So what am I getting at?
To get right to the point, my suggestion to all rule designers and particularly to developers is to avoid treating your rules engine like it’s a technical collection of rules data to be extracted and processed in your code and instead consider that your business rule is there to make a business decision within your program. In other words, your rule contains both business rule data and business rule logic and therefore you shouldn’t just look to kill your Z-tables but kill the custom code that represents the decision too. This might mean a shift in thought for some folks as it means pushing the boundaries of comfort and moving some of the program control from a familiar environment (your code) to a potentially unfamiliar one (your rules engine) but I guarantee that doing this will help you design and build your rules more easily and more simply.
One way that I’ve found to test your business rule definition to see whether it’s making a true and complete business decision as opposed to a being just a Z-table replacement is to write out its purpose as a sentence using business terms/phrases. If the purpose of your rule is something like “Get purchase requisition types that can be auto-approved” then you’re probably not using the rules engine to make a complete business decision and that the rest of the rule is implemented elsewhere in code. However, a rule like “Can this purchase requisition be auto-approved?” is asking a question of the rules engine and allowing it to make the decision in any way it sees fit, so is likely to be more complete. Notice that the second rule asks a question rather than making a demand of the rules engine? Generally speaking, I’ve found that questions with yes/no answers (“Is …?”, “Can …?”, “Should …?”) make more useful and more reusable rule definitions than others but, as with anything in life, there are always exceptions to this “rule”.
1000 words is too long, time to wrap this up quickly
I hope this post has helped to highlight a change in thinking that is required when designing and implementing rules in a rules engine as opposed to custom code + custom table and that you need to consider killing custom code, not just Z-tables. I’d love to hear others’ opinions on this and especially if you have other tips or techniques for good rules design.
A more appropriate title for my blog might have been “A Business Rules Engine Should Not Just Replace Z-Tables…” but it might not have been as thought-provoking. Or attention-grabbing. 😉