Violating CQS. Looking For Suggestions And Alternatives.
When doing simple input validation on forms, I often end up writing a lot of code like this:
public void SaveRequested()
{
bool descriptionIsValid = ValidateDescription();
bool abbreviationIsValid = ValidateAbbreviation();
bool isValid = (descriptionIsValid && abbreviationIsValid);
if (isValid)
{
VisitType visitType = new VisitType(Description, Abbreviation);
VisitTypeRepository.Save(visitType);
}
}
private bool ValidateAbbreviation()
{
bool isValid = !string.IsNullOrEmpty(Abbreviation);
if (isValid)
View.HideAbbreviationRequiredMessage();
else
View.ShowAbbreviationRequiredMessage();
return isValid;
}
private bool ValidateDescription()
{
bool isValid = !string.IsNullOrEmpty(Description);
if (isValid)
View.HideDescriptionRequiredMessage();
else
View.ShowDescriptionRequiredMessage();
return isValid;
}
</div> </div>
I recognize the violations of Command-Query-Separation in this code, and potentially other issues in design and implementation. The ValidateDescription and ValidateAbbreviation methods are fairly horrendous, from a CQS perspective. They are both querying the data to see if it’s valid, and also executing commands if it is or is not valid. Then on top of that, the SaveRequested method is executing another set of commands if both Description and Abbreviation are valid.
The requirements of this functionality are:
- If Description is null or empty, show the “Description Required” message
- If Abbreviation is null or empty, show the “Abbreviation Required” message
- If both Description and Abbreviation are ok, allow the save to happen.
I’m not considering the difference between active and passive validation (on typing, vs on clicking save) in this example. That’s a different discussion for a different time.
So, how do you handle this type of input validation, accounting for CQS, code readability, testability, etc? I’m looking for suggestions and alternatives to this type of ugly code. I have a lot of my own ideas, but before I travel too far down the road, I want input from the rest of the world.
Note On Responses: As a suggestion for responding – if your response will take more than a few lines of very simple code and text, I’d really like to see your full response on your blog. Post a comment here (or pingback/trackback from your post) when you have your post up. If you don’t have a blog to respond with – shame on you! Blogspot.com is free. Go get a blog and respond. 🙂