Альтернатива для слишком большого количества переключателей для уменьшения цикломатической сложности?

У меня есть функция для проверки типа значения $ является действительным или нет. Мой текущий код — это простой случай переключения, в котором слишком много случаев превышает цикломатическую сложность до 17. Мне нужно добавить больше случаев, а также уменьшить сложность.

 /**
* Check type of attribute value
* @param $type
* @param $value
* @return bool
*/
public function typeCheck($type, $value)
{
$this->value = $value;
switch ($type) {
case 'string':
return is_string($value) || is_integer($value) || is_bool($value);
case 'StringNotNull':
return is_string($value);
case 'LongStringNotNull':
return is_string($value);
case 'SuperLongStringNotNull':
return is_string($value);
case 'FortyStringNotNull':
return is_string($value) && (strlen($value) < 41);
case 'integer':
return is_numeric($value);
case 'positiveInteger':
return is_numeric($value) && ($value > 0);
case 'boolean':
return is_bool($value) || ($value == 'true' || $value = 'false');
case 'float':
return is_numeric($value);
case 'decimal':
return is_numeric($value);
case 'PositiveDimension':
return is_numeric($value) && ($value > 0);
case 'Dimension':
return is_numeric($value) && (strlen($value) < 13);
case 'Barcode':
$validator = $this->getBarcodeValidator();
$validator->setBarcode($value);
return is_string($value) && (strlen($value) < 17 && $validator->isValid());
case 'dateTime':
return true;
case 'normalizedString':
$this->value = strip_tags($value);
return is_string($value);
default:
return is_string($value);
}
}

Есть способ лучше?

1

Решение

Вы можете заменить переключатель структурой данных:

private

public function typeCheck($type, $value) {

$typeTestMap = [
'string' => function($value) { return is_string($value) || is_integer($value) || is_bool($value); },
'FortyStringNotNull' => function($value) { return is_string($value) && (strlen($value) < 41); },
...
];

if (isset($typeTestMap[$type])) {
return $typeTestMap[$type]($value);
} else {
return is_string($value);
}
}
1

Другие решения

Ну, вы можете сгруппировать те, которые имеют одинаковую функциональность:

public function typeCheck($type, $value)
{
$this->value = $value;
switch ($type) {
case 'string':
return is_string($value) || is_integer($value) || is_bool($value);
case 'FortyStringNotNull':
return is_string($value) && (strlen($value) < 41);
case 'positiveInteger':
return is_numeric($value) && ($value > 0);
case 'boolean':
return is_bool($value) || ($value == 'true' || $value = 'false');
case 'float':
case 'decimal':
case 'integer':
return is_numeric($value);
case 'PositiveDimension':
return is_numeric($value) && ($value > 0);
case 'Dimension':
return is_numeric($value) && (strlen($value) < 13);
case 'Barcode':
$validator = $this->getBarcodeValidator();
$validator->setBarcode($value);
return is_string($value) && (strlen($value) < 17 && $validator->isValid());
case 'dateTime':
return true;
case 'normalizedString':
$this->value = strip_tags($value);
return is_string($value);
case 'StringNotNull':
case 'LongStringNotNull':
case 'SuperLongStringNotNull':
default:
return is_string($value);
}
}

Это уменьшит ваш CRAP Индекс немного. Однако, если вы используете OO, вам следует подумать об использовании Strategy шаблон, посмотрите здесь для получения дополнительной информации https://phpenthusiast.com/blog/strategy-pattern-the-power-of-interface

1