Separation of business rules from requirements is a good thing. Not because of semantic distinctions, but because it allows you to write better software, write it faster, and change it more easily. This article is a response to an excellent comment on our recent article about hidden business rules. Thanks for challenging the idea – it either eliminates it from discourse or makes it stronger, and we all benefit. Here’s an attempt to make it stronger.
Goals of Separating Rules from Requirements
Writing software ultimately involves coding up an implementation that both satisfies the goals of the customers and enforces the rules by which that customer chooses to achieve the goals. This is the traditional way to write software – define the goals, and all of the enhancing, constraining, and clarifying details, then implement it. There are some inefficiencies to this approach, but they are in the “getting great at writing software” bucket, not the “avoiding failure at writing software” bucket. Consider this the medium priority goal of separating rules from requirements. In a Kano analysis, this is a more-is-better benefit.
When we set out to write software, it is with intent. That intent encompasses processes, rules, and requirements. The combination of all of these could be described as a summation of intent.
Maintaining software is expensive. When you design an implementation, you (should) think about what is likely to change when making your design decisions. The greater the probability or frequency of change, the easier it should be to make those changes.
Intent changes. Agile processes start with a premise that even if the true intent were fixed, our understanding of intent would change, as soon as we get what we asked for. In practice, both our understanding of intent, and the actual intent change over time. To make the language less cumbersome, for the rest of this article, when I refer to intent it is our understanding of intent – and changes to intent represent both changes in the true intent, and changes in our understanding of it.
When developers think about software maintenance, they often think about it in terms of bugs and features. What needs to be fixed, and what needs to be added (or removed)? To make a significant impact on the cost of maintenance, we have to take that perspective to the next level. Set aside fixing bugs (where bugs are “does not work per the requirements”), and think about the new features. The new features truly represent new intent. Or in an agile process, it may be the recently revalidated, previously identified, next most valuable intent.
In both cases, intent is a moving target, and changes in intent drive changes to the existing software. To minimize the cost of making those changes, our implementation should be structured such that the most common changes are trivial to implement – ideally, they won’t even require changes to the code. When you can change the behavior of an application without recompiling the application, you significantly reduce the effort required to define,develop,test and deploy an update to the application. And you can also dramatically reduce the time required to make the change.
This is the high priority goal of separating rules from requirements: increase the speed, and decrease the cost of changing software to match changes in intent. I’ll say it again in bold.
The primary goal of separating rules from requirements is to increase the speed and decrease the cost of updating software to match changes in intent.
While the cost reduction part of it is nice, it is the speed element that can be the most compelling. James Taylor and Neil Raden wrote about this in their book, Smart Enough Systems. We accept the premise that abstracting the implementation of volatile rules from the rest of the software provides benefits in speed of delivery on an ongoing basis. And that is the primary driver for the separation of rules from requirements. If you don’t accept that premise, then the only benefit comes from improved documentation style, structure, and standardization – all somewhat subjective benefits.
Visualizing The Benefits
Here’s a timeline showing the benefit of agility – being able to deploy and update faster.
The maroon curve represents “traditional” deployment – where the implementation of volatile rules is no different than the implementation required to support requirements. It will take longer to deploy initially (but not necessarily much longer), and it will take longer to make changes (when the rules have been changed). The upward sloping line starts displaying accumulated value as soon as the software is released. When the next iteration is released, the rate of value accumulation will go up. There is one iteration displayed in the timeline.
The green curve represents deployment with volatile rules abstracted in the implementation. This could be as low-tech as implementing field-level validations in a properties file (that is interpreted by the application), or as high-tech as integration with a rules-processing engine or service. This implementation begins accumulating value a little bit earlier, but at the same rate (keeping prioritization and other factors equivalent). The first iteration happens more quickly, so the slope of the curve increases earlier. The length of iteration has been shortened enough that a second iteration can also happen. This further increases the relative rate of accumulation of value. The longer this pattern goes on, the greater the disparity.
Encouraging This Behavior
Abstracting the rules from the requirements will make it easier for developers to absorb and design for those rules. Further, once the rules have been separated from the requirements, it is easier to identify which rules are the volatile rules. And that enables developers to make smart decisions about when to abstract the implementation, and when to embed it.
You could abstract only the volatile rules from the requirements, and leave other rules embedded within the requirements. There are three good reasons for separating all of the rules from the requirements.
The first reason is one of consistency of documentation, and arguably style. Your communication will be more effective when consumers of the documents know that all rules are treated in the same way. If developers have to look in the requirements for some rules, and a table of rules for others, they are more likely to miss something. Subject matter experts who are validating the rules will also be able to do that job more effectively when they are documented similarly.
The second reason is that by separating all of the rules, you will better be able to identify the ones that are volatile. You can more easily evaluate the rules as a whole, and formally or informally characterize their frequency and likelihood of change. The rules for management of available products and the calculation of risk in a portfolio are likely to change frequently. The rules that represent FAA regulations are likely to change infrequently. You can better assess this data when dealing with a cohesive set of rules.
The third reason is that separation of the rules will imply to developers that they should at least consider separation of the implementation. Especially if, in your documentation approach, you identify which rules are volatile.
Conclusion
There are differences in rules and requirements. While the content of how they are used when developing software may be only semantic, there are practical benefits to separating them. Separation of rules and requirements in a documentation approach will make it easier for your development team to implement solutions that separate volatile rules from the rest of the code.
And this separation will make the software more valuable, more quickly.
Yes, there are benefits from separating business rules from other requirements, just as there are benefits from separating out data requirements, GUI standards and workflow (to name but three other types of requirement). And the costs of separating them out tend to be negligible (so long as nobody gets into prolonged discussions about how to separate them).
I’m not sure that it allows you to write better software, faster. But I would suggest that it allows you to start writing it sooner. This is a good example of the benefits of an iterative approach. Once the design decision has been made about how a business rule will be implemented, some of the details (and it should be clear which ones) can be left to be finalised later in the development process, so they are removed from the critical path. It is a good rule of thumb that the longer it takes the stakeholders to define their business rule for you, the more likely it is to change… and sooner rather than later.
Another good rule of thumb, though, is that the more you abstract the implementation of business rules, and the more you try to make it easy to maintain them, the higher your costs will be… initially. So I would quibble with your otherwise excellent graph. I think the general case should be that the maroon line begins by leading the green line (a small decrease in time to deploy) and the green line crosses it later. How much later will depend on the extent to which, for the green line, there was worth-while investment in enabling the future timescales to be shorter. So the bigger the initial delay, the less time is required for each iteration and the greater the “acceleration”.
In conclusion, I would note that you omit one very good reason for abstracting “all” rules, rather than only the more volatile ones. This is that making a distinction based on volatility would imply a design decision. (From a theoretical standpoint, I don’t believe it is actually possible to abstract all rules, since you would, if successful, end up with only rules. So from a practical standpoint: How do you recognise what not to abstract?)
Interested readers might like to consider divergent opinions here:
In this comment, AlanAJ is a link to this website: http://c2.com/cgi/wiki?BusinessRulesMetabase
That’s why we’ve created BLEX (Business Logic Express), it’s a visual language that allows to declare rules, actions and tests.
Belive me, when you start using something like this, the green line is growing even faster and there is no reason to hide businness logic in the code.
“All the variables are constants, all the constants are variable”
Hi there. Great post. Too many analysts get caught up in business rules and design, confusing themselves and the business.
Cheers,
http://www.snjtechconsulting.com.au/
Thanks all for the comments!
In reply to AlanAJ, you wouldn’t end up with a system that was composed solely of business rules.
A radio receiver receives a signal composed of some carried content, and a carrier wave. The carrier wave has a fixed frequency and modulation. The radio removes the carrier wave from the signal,and then outputs the signal to the speaker.
Software does the same thing. In the “Hello World” program, the text “Hello World is the carried content. The rest of the code is carrier. We’ve written this program in a wide variety of programming languages and technologies. In the end, regardless of the various implementations, the program just display “Hello World.”
Carrier and carried is a generic characteristic of all media with software being a media.
In code, we make decisions in the carrier as well as in the carried. In business rules technology, the carrier is the responsibility of the programmer, and the rules are left to business managers. The carrier decisions can be left to the requirements. The carried decisions will constitute the business rules of the application.
It might be beneficial to treat the carrier decisions as rules, since they are volatile, but it will be critical that the carried decisions be business rules.
The real savings with business rules technology is that the manager will no longer need programmer support to change a business policy. With business rules technology, a manger change the policies driving their organization quickly, so the business will be more responsive to real world business drivers.