Php 为减少圈复杂度而选择过多开关情况?

Php 为减少圈复杂度而选择过多开关情况?,php,if-statement,switch-statement,cyclomatic-complexity,Php,If Statement,Switch Statement,Cyclomatic Complexity,我有一个函数来检查$value的类型是否有效。我当前的代码是一个简单的切换用例,有太多的用例超过圈复杂度到17。我需要添加更多案例,同时降低复杂性 /** * Check type of attribute value * @param $type * @param $value * @return bool */ public function typeCheck($type, $value) { $this->value = $value; switch (

我有一个函数来检查$value的类型是否有效。我当前的代码是一个简单的切换用例,有太多的用例超过圈复杂度到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);
    }
}
/**
*检查属性值的类型
*@param$type
*@param$value
*@returnbool
*/
公共函数类型检查($type,$value)
{
$this->value=$value;
交换机($类型){
大小写“string”:
返回值为_string($value)| |为_integer($value)| |为_bool($value);
案例“StringNotNull”:
返回值为字符串($value);
案例“longstrignotnull”:
返回值为字符串($value);
案例“SuperLongStringNotNull”:
返回值为字符串($value);
案例“FortyStringNotNull”:
返回值为字符串($value)&(strlen($value)<41);
“整数”情况:
返回值为数字($value);
案例“积极参与者”:
返回值为数值($value)&($value>0);
“布尔”大小写:
返回值为_bool($value)| |($value='true'| |$value='false');
“浮动”案例:
返回值为数字($value);
“十进制”大小写:
返回值为数字($value);
案例“阳性测定”:
返回值为数值($value)&($value>0);
案例“维度”:
返回值为数字($value)&(strlen($value)<13);
“条形码”案例:
$validator=$this->getBarcodeValidator();
$validator->setBarcode($value);
返回值为字符串($value)&&(strlen($value)<17&&$validator->isValid();
案例“日期时间”:
返回true;
大小写“normalizedString”:
$this->value=strip\u标签($value);
返回值为字符串($value);
违约:
返回值为字符串($value);
}
}

有更好的方法吗?

好吧,您可以将具有相同功能的功能分组:

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);
    }
}
公共函数类型检查($type,$value)
{
$this->value=$value;
交换机($类型){
大小写“string”:
返回值为_string($value)| |为_integer($value)| |为_bool($value);
案例“FortyStringNotNull”:
返回值为字符串($value)&(strlen($value)<41);
案例“积极参与者”:
返回值为数值($value)&($value>0);
“布尔”大小写:
返回值为_bool($value)| |($value='true'| |$value='false');
“浮动”案例:
“十进制”大小写:
“整数”情况:
返回值为数字($value);
案例“阳性测定”:
返回值为数值($value)&($value>0);
案例“维度”:
返回值为数字($value)&(strlen($value)<13);
“条形码”案例:
$validator=$this->getBarcodeValidator();
$validator->setBarcode($value);
返回值为字符串($value)&&(strlen($value)<17&&$validator->isValid();
案例“日期时间”:
返回true;
大小写“normalizedString”:
$this->value=strip\u标签($value);
返回值为字符串($value);
案例“StringNotNull”:
案例“longstrignotnull”:
案例“SuperLongStringNotNull”:
违约:
返回值为字符串($value);
}
}

这将稍微减少你的
垃圾
索引。但是,如果您正在使用OO,您可能应该考虑使用
策略
模式,在这里查看更多信息

您可以用数据结构替换交换机:

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);
    }
}
公共函数类型检查($type,$value){
$typeTestMap=[
'string'=>函数($value){返回的是(字符串($value)| |是(整型($value)| |是)布尔($value);},
'FortyStringNotNull'=>函数($value){返回的是字符串($value)&&(strlen($value)<41);},
...
];
if(isset($typeTestMap[$type])){
返回$typeTestMap[$type]($value);
}否则{
返回值为字符串($value);
}
}

要使代码更易于测试,请在每次类型检查中创建对象方法


公共函数isTypeString($value){
返回值为字符串($value);
}
公共函数IsTypeLongStringNotFull($value){
返回值为字符串($value);
}
现在您可以通过两种方式调用这些方法。您可以像以前一样将
$type
传递给
typeCheck()
,也可以使用一些神奇的方法或直接调用
isType…()
方法

//什么都可以
/**
*检查属性值的类型
*@param$type
*@param$value
*@returnbool
*/
公共函数类型检查($type,$value)
{
$this->value=$value;
如果(方法_存在($this'isType'.ucfirst($type)){
返回调用用户函数([$this,'isType'.ucfirst($type)],$value);
}
返回此->isTypeString($value);
}
公共函数调用($method,$args){
返回调用用户函数数组([$this,'isType'.ucfirst($type)],$args);
}
//}类
//调用类型检查方法的3种方法
//常规方式
$x=新的任何内容();
$x->typeCheck('longstrignotnull',$val);
$x->IsTypeLongStringNotFull($val);
//神奇的呼叫
$x->LongStringNotNull($val);
//字符串插值
$check='LongStringNotNull';
$x->{$check}($val);
$x->{'isType'.$check}($val);

非常感谢。我不知道PHP支持匿名函数。而且,我的PhpStorm在编写代码时仍然抛出语法错误,您是否已经遇到了这个问题?您不能使用数组作为静态变量的初始值。我已将其重新编码为仅使用普通局部变量。