Problem #6: Functions that do more than one thing
An effective function should ideally do only one thing
An effective function should ideally do only one thing so that we can call it from different places in the code knowing with full confidence that it will only do exactly what it is supposed to do, and nothing else. Therefore, care should be taken that any function you write has only a single responsibility.
In the following example, the function validatePhoneNumberThenWrapInHtml does two things:
- checks if a string is a valid phone number
- outputs the phone number or a warning wrapped in html
function validatePhoneNumberThenWrapInHtml($string)
{
//replace all the non-digit characters
$onlyDigits = preg_replace('/[^0-9]/','',$string);
// checks if the length of the remaining string
// is 7-14 characters long
$onlyDigitsLen = strlen($onlyDigits);
$isValidPhoneNumber = ($onlyDigitsLen >= 7 && $onlyDigitsLen <= 14);
// a warning if it is not a phone number
if(!$isValidPhoneNumber) $onlyDigits = "Not a phone number";
// return the phone number wrapped in html
return "<p>{$onlyDigits}</p>";
}
Let's check the function with a valid and non valid strings:
var_dump(validatePhoneNumberThenWrapInHtml("1-800-123-4567"));
var_dump(validatePhoneNumberThenWrapInHtml("1-800-123-45678910"));
Result
string '<p>18001234567</p>' (length=18)
string '<p>Not a phone number</p>' (length=25)
As we can see, the function validates the phone number and then returns the result wrapped in html. This means that we can't use the function each time we want to check the validity of a phone number since it doesn't return a boolean (true or false) value, but rather returns html. The implication is grave since we'd have to repeat ourselves and write the validation code again and again in every function that needs to check the validity of a phone number. This can introduce duplication in our code, whereas duplication is something that we strive to eliminate (see problem #5).
So a better solution is to separate the function into two functions, each having only a single responsibility. The functions are:
- validatePhoneNumber that validates phone numbers
- wrapInHtml that wraps the result in html
function validatePhoneNumber($string)
{
//replace all the non-digit characters
$onlyDigits = preg_replace('/[^0-9]/','',$string);
// checks if the remaining string
// is 7-14 characters long
// and return boolean (true/false) value
$onlyDigitsLen = strlen($onlyDigits);
return $isValidPhoneNumber = ($onlyDigitsLen >= 7 && $onlyDigitsLen <= 14);
}
function wrapInHtml($string)
{
// return the string wrapped in html
return "<p>{$string}</p>";
}
// check the 2 functions
$string = "1-800-123-4567";
$isValidPhoneNumber = validatePhoneNumber($string);
var_dump(($isValidPhoneNumber)? wrapInHtml($string) : wrapInHtml("Not a valid phone number"));