Let he who hasn’t got lost in dozens of business logic of a project cast the first stone!
Sometimes the business logic of a project can be many and also complex, leading us to write a messy code, therefore making it hard to read!
What we would like to be an easy-peasy code, turns it into a boring and discouraging thing, for us and for the next developer that might have to read it.
Back in time, the Microsoft MVP and now also a Microsoft Director, Eduardo Pires, once taught about a Specification pattern which helped me a lot to reorganize all those rules and validations.
The idea of this pattern is to make it more atomic (see the SOLID principles), helping us to reuse code and making our validations more readable and intuitive.
Let’s start coding!
Consider the entity
We must validate some fields before inserting in our database, otherwise we might face some database exceptions, such as inserting null in a non nullable field.
Also we can’t just let it to the front-end to make validations before it comes to our server.
Remember that there are still ways to mock some posts/forms, so it’s better to make validations on both sides.
Let’s code our method
Add that will do some validations to insert our
Person into our database:
Notice that we need a lot of IFs to validate our entity.
From checking if fields are null to more specific validations, such as CPF validation (Brazilian document).
It works fine, right? Yes! But.. if we try the specification pattern with Eduardo Pires’ package, the DomainValidation? Can we make it better?
First things first, we need to download the package via NuGet:
And now we should code our specifications. Basically they’ll be exactly our ifs in our previous code:
Once done, we now code our validation and modify our service like this:
We got a cleaner code and we can tell that their atomicity is now on a good level, making our specifications reusable for any other validation!!
Ok, we got it.. But let’s go further!
As a bonus section, I would like to refactor our specifications. It’s bad to see many of them just to do a
string.IsNullOrWhiteSpace(), isn’t it?
So it’s time to make it easier with lambda expressions:
Now we got only 2 (and totally reusable) specifications for the entire validation!!
And if we look closely, we can easily read and understand what we are validating.
Generics and lambda expressions are awesome!