2

我有一个类,它接收文本行并使用大约 15 种不同的“标准”(单独的 preg_match 语句)来检查该行是否有资格保存在数组中。

如何使用干净、可维护的代码最好地处理这种情况?

最初,我有一个疯狂的长 if 语句,它具有所有标准,例如:

if (
    preg_match($criteria1,$line) &&
    preg_match($criteria2, $line) &&
    ...
    ...
    ...
    preg_match($criteriaN,$line)
) {
    //do something, e.g. save the line to an array.
}

从那以后,我将每个 preg_match 语句放入一个单独的类中的不同函数中,并连续调用每个函数,检查它是否为真……但现在我有 15 个单独的函数,它们之间只有细微的不同,但它仍然没有'感觉不像我在写好的代码。如何最好地处理这种情况?

4

3 回答 3

1

简单的例子:

$rgCriterias = [$sCriteria0, $sCriteria1, $sCriteria2];
if(!count(array_filter($rgCriterias, function($sCriteria) use ($line)
{
   return !preg_match($sCriteria, $line);
})))
{
   //do the stuff
}
于 2013-08-15T14:37:17.723 回答
1

好吧,如果你想保持面向对象的东西,你可以使用这样的类......

class Validator{

    /* Any criteria needing to be met must exist in this array */
    public static $criterias = array($criteria1,
                                      $criteria2,
                                      ... ,
                                      $criteriaN);



    public static function validate($line){

        /* Make sure this line meets each criteria */
        foreach(Validator::$criterias as $criteria){

              if(!preg_match($criteria, $line))
                   return false;
        }

        return true;
    }

将方法和属性设置为静态是有意义的,因为它们对于任何实例都是唯一的。然后你可以简单地通过调用来检查一条线是否符合条件

Validator::validate($line)
于 2013-08-15T14:56:00.227 回答
0

可能有点矫枉过正,但您可以使用Specification Pattern。一个非常简化的例子是:

abstract class Specification
{
    abstract public function isSatisfiedBy($obj);
}

class RegExSpecification extends Specification
{
    private $_pattern;

    public function __construct($pattern)
    {
        $this->_pattern = $pattern;
    }

    public function isSatisfiedBy($obj)
    {
        return preg_match($this->_pattern, $obj);
    }
}

用法:

class YourLinesProcessor
{
     private $_specs;

     public function setSpecs($specs)
     {
         $this->_specs = $specs;
     }

     public function check($line)
     {
           foreach ($this->_specs as $spec)
                $satisfied = $spec->isSatisfiedBy($line);

           if ($satisfied)
               // do something
     }
}

$specs = array();
$specs[] = new RegExSpecification("\some\pattern");
$specs[] = new RegExSpecification("\another\pattern");

$processor = new YourLinesProcessor();
$processor->setSpecs($specs);
$processor->check("line_data");
于 2013-08-15T15:07:01.697 回答