dongshiqin1352
dongshiqin1352
2013-08-15 14:33

如何最好地使用OOP原则来处理具有10-15 +匹配标准的情况,这些标准都需要通过?

已采纳

I have a class that takes in lines of text and uses about 15 different "criteria" (individual preg_match statements) to check if the line should qualify to be saved in an array.

How does one best handle such a situation with clean, maintainable code?

Initially I had a crazy long if statement which had all the criteria, for example:

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

I've since put each preg_match statement into a different function within a separate class and call each function in a row, checking if it's true... But now I have 15 separate functions that are only subtly different from each other and it still doesn't feel like I'm writing good code. How is it best to handle this situation?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • doujuncuo9339 doujuncuo9339 8年前

    Well, if you want to keep things object oriented, you could use a class like this...

    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;
        }
    

    It makes sense to have the methods and properties static because they are unique to no instance. Then you can simply check to see if a line meets the criteria by calling

    Validator::validate($line)
    
    点赞 评论 复制链接分享
  • douwen9343 douwen9343 8年前

    Might be an overkill, but you can use the Specification Pattern. a very simplified example would be:

    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);
        }
    }
    

    Usage:

    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");
    
    点赞 评论 复制链接分享
  • drmy1050 drmy1050 8年前

    Simple example:

    $rgCriterias = [$sCriteria0, $sCriteria1, $sCriteria2];
    if(!count(array_filter($rgCriterias, function($sCriteria) use ($line)
    {
       return !preg_match($sCriteria, $line);
    })))
    {
       //do the stuff
    }
    
    点赞 评论 复制链接分享