I don't know how to refactor a piece of code that differs from other in the number of conditions checked on an if
clause. Let me show you a real world example I'm facing right now.
The only difference between the two methods is that on the inner elseif
, it checks an additional condition on the new parameter.
Method 1:
public function getKeysToInvalidateOnCreation($entity, $allKeys)
{
$result = [];
foreach ($allKeys as $key) {
$entities_in_key = explode('+', substr($key, 0, strpos($key, '_')));
$key_type = substr($key, strrpos($key, '_'));
foreach ($entities_in_key as $entity_in_key) {
if ($entity_in_key == $entity) {
if ($key_type == self::GET_ALL_KEY || $key_type == self::CUSTOM_KEY) {
$result[] = $key;
} elseif (strpos($key, 'id:') === false) {
$result[] = $key;
}
}
}
}
return $result;
}
Method 2:
public function getKeysToInvalidateOnModification($entity, $allKeys, $modifiedId)
{
$result = [];
foreach ($allKeys as $key) {
$entities_in_key = explode('+', substr($key, 0, strpos($key, '_')));
$key_type = substr($key, strrpos($key, '_'));
foreach ($entities_in_key as $entity_in_key) {
if ($entity_in_key == $entity) {
if ($key_type == self::GET_ALL_KEY || $key_type == self::CUSTOM_KEY) {
$result[] = $key;
} elseif (strpos($key, 'id:') === false ||
strpos($key, 'id:'.$modifiedId) !== false) {
$result[] = $key;
}
}
}
}
return $result;
}
What I would do is to extract all the inner code to a new protected method that would have the third parameter as optional, and then do the second check only if that parameter is set. But that has kind of bad smell for me: it seems like adding a flag to the method.
What would be the appropriate refactoring strategy?