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.
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.