Description:
Any method, which the name hints the intent of validation (eg: PhoneValidation, TryValidateEmail, etc) should:
- Take a single input
- Return a boolean or a instance of a object/struct
- Do not explicitly throw any kind of Exception
- Should not change the input
WHY?
- Single responsibility: One validation, one input…
bad code:Validate(CompleteAddress addr, SocialSecurityNumber ssn)
good code:Validate(CompleteAddress addr); Validate(SocialSecurityNumber ssn);
- When you validate something, you expect a true/false or a detailed/structured response explaining where is the problem
bad code:public string ValidatePhone(string phone)
good code:public bool ValidateLogin(Credentials cred)
orpublic ValidationSummary ValidateAddress(CompleteAddress addr)
- A validation method should not alter the input parameter because a validation is generally understood as a idempotent operation. A common violation of such principle is when you also “format” the input, eg: string “+5531999914162” after validation becomes “+55 (31) 99991-4162”
- Throwing exceptions is a established bad practice except when you’re dealing with a real unexpected code path… it is not a shortcut to “end the function”, so if you comply with proposition number 2, you won’t need to throw an exception.
bad code:
if (phoneNumber.Length < 10)
throw new ArgumentInvalidException("Phone must be 10 digit long")
good code:
if (phoneNumber.Length < 10)
return false;
or
if (phoneNumber.Length < 10)
return new Summary(false,"Phone must be 10 digit long");