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. 😉
I'm glad you finally found some time to share your thoughts. Hope it's not an one and done thing 🙂
totally agree, we should aim to kill not only the Z tables but some code too, although writing code is much more fun than creating the rules in BRF+ 😉
Me too! I have other blogs on the boil but my editor (me) is quite harsh. 😛
I think you're joking but your comment needs a response anyway...
Now that I'm relatively proficient, I find that designing and building rules in BRF+ is just as "fun" as writing code. Logic is logic and the mental process to produce it is the same, regardless of the implementation. I think the fun is lost when the tool and the syntax is unfamiliar and new but that quickly fades as experience grows.
Thanks for commenting. 🙂
This is a very important contribution. I am happy that people like you share experience and opinion about the topic. Thank you very much for it. I am looking to read more from you in the future.
I fully agree to your blog and I want to add another perspective:
Some developers find it easy to start with replacing a Z-table by a decision table. It does not force into new thinking and code redesign and is therefore quickly done. As soon as they see how a decision table works (ranges in the cells etc.) they start thinking about more. They learn that decision tables can have big advantages, and transfer the approach to other use cases.
I have seen customers that use decision tables are replacements of Z-tables for another reason. With NW DSM they can easily update the content in the productive system without transport, and they further benefit using more DSM features (execution analytics, unit tests etc.).
Thanks very much.
Yep, I agree that some developers intuitively learn to trust the rules engine (BRFplus or otherwise) with more of their rules logic as they discover more of its features and abilities... maybe this blog post might help them short cut that process? However I have also seen developers get increasingly frustrated with BRFplus, particularly if it has been forced on them by project standards/guidelines, and I believe this is because they continue to view decision tables as simply a place to store and retrieve data. I hope this post will help to change those views, even a little.
Thanks for posting this! I have experienced exactly the same in my project and I could not have put it better.
I would particularly like to emphasize one aspect:
I believe that when defining a rule you actually define an interface between varying parts of your application logic and static ones. Thinking not of the implementation of the possible variations but of what might be relevant in one particular context in order to decide about what helps avoiding the fall into the pit you were describing. At least for me.
If I understand you correctly, you're suggesting that when defining the rule we shouldn't just be thinking about which specific input fields are required today but should instead think about the complete context of the decision that is being made and therefore what input data might be required in the future. If so then you've just touched on the topic I was planning for my next blog post. 🙂
Exactly, Glen. As a good developer, I restrict an Interface of a method to be as compact as possible (e. g. not to pass any exclusively optional parameters). But when I think of the interface to a rule, I got the impression that it's wiser to think outside the box of the current usage-context.
I'm looking forward to reading your next post then, as it reduces my communication efforts towards my team 😉
Very interesting discussion. From my part I have created a solution coming from my participation to several projects (and I have created 2 SAP partners solution).
- a concept of mother class, children casse, managing businesses rules
- cutomizing tables to manage them with validity period..
- I implement a client on each systems.
I may use my solution to be used in all SAP NETWEAVER systems, using ABAP (:)).
I may use it to merge all extensions, from user exit to BADIS
I may use it to manage all data requirements, for all specifics reports, interfaces, printings, workflow.
After to allow controls I am using reports to allow abapers to check their policies by following a check list (we may adapt it to needs....).
At least, a server may check all systems using my solution, to check differences if needed.
From a version to another version, I may check differences.
I have added predicative function to allow abaper to check their modification in the future, and allow to tranport all modification without impacting enduser before milestones.
SAP et SCRUM / AGILE
I may at least develop my requirements by using AGILE, paralelize developments....
At the bottom of the page, you will have english documents. I did not explain everything in this message.