I’m studying the SOLID principles and I’m having some troubles dealing with the Specification Pattern and the open/closed principle.
The fact is that the Specification pattern introduced by Eric Evans and Martin Fowlers creates some abstraction and a really open way to manage business rules.
But I was wondering if it was really based on Open/closed principle.
The fact is that, when we need a new rule, we can extend it from our parent specification class.
So, it’s open in extension, that is a good point from a SOLID point of view.
On the other hand, specification pattern is based on rules combination, so we have to modify the rules code, or at least, the parent rule code. This way, we’re open in modification in a class that, in my mind, should not be modified.
I’m probably missunderstanding something in this process.
Can anybody explain me:
- How does (if it’s the case) the specification pattern respect the OC principle ?
- Does it exist an alternative to this pattern ?
The SOLID principles are most useful for writing reusable software components, like libraries or frameworks, and the OCPs idea is to create them in a manner to prevent unnecessary changes afterwards, even when requirements are extended or changed.
The Specification Pattern, as far as I understand it, is about creating complex business rules from small rule building blocks. So for this scenario, the reusable parts are the rule building blocks, not the aggregated business rules itself. And as you mentioned by yourself, the spec pattern provides you with a design where the set of rule building blocks can be easily extended without any change to other building blocks or infrastructure, so it follows the OCP.
However, when a complex business rule changes, you obviously have to change something in your system, and that is obviously the part where that business rule is defined. There is no pattern which can prevent the need for changes in the system completely when the rules change.
The only thing you can do here is to design the system in a way that the part which need to be changed is not buried somewhere deep inside the code, but moved to a place where it can be edited by changing a separate configuration instead. This allows to shift the responsibility for changing to some degree from the developers to someone else, for example to the user of your system. So users may create or change complex business rules from the building blocks you provide for them.
The typical approach for this is to create a DSL for this where the DSL elements refer to the elementary rules and the operators you defined using the spec pattern. The DSL code then can be stored in a config file which is maintained or extended by someone who is not the developer of the system, maybe a user or a “power user”.
I was asked in one of the comments to provide some examples of rule based languages. The links here list some languages. I created a custom rule based language in the past, specific to the process control industry. You can either create your own language or use an existing one, but it is helpful to understand various algorithms if you create your own:
- Rete algorithm An older algorithm underlying many languages.
- Production system General description of production rule systems, and example languages.
For me, the most interesting thing about some rule systems, from an end user perspective, is they way they automatically revert state back to a default when no rule applies.