一天一个设计模式(8)——过滤器模式

过滤器模式

  过滤器模式非常容易理解,简单来说就是设计一组类来过滤对象。

实例

  需要过滤的类:

class Person
{
    public $name;
    public $gender;
    public $maritalStatus;

    function __construct($name, $gender, $maritalStatus)
    {
        $this->name = $name;
        $this->gender = $gender;
        $this->maritalStatus = $maritalStatus;
    }
}
Bin_x

  过滤器接口:

interface Criteria
{
    /**
     * @param $persons Person[]
     * @return Person[]
     */
    public function filter($persons);
}
Bin_x

  实现接口的类:

class MaleCriteria implements Criteria
{

    /**
     * @param $persons
     * @return Person[]
     */
    public function filter($persons)
    {
        $result = [];
        foreach ($persons as $person) {
            if (strtolower($person->gender) === 'male') {
                $result[] = $person;
            }
        }
        return $result;
    }
}

class FemaleCriteria implements Criteria
{

    /**
     * @param $persons
     * @return Person[]
     */
    public function filter($persons)
    {
        $result = [];
        foreach ($persons as $person) {
            if (strtolower($person->gender) === 'female') {
                $result[] = $person;
            }
        }
        return $result;
    }
}

class SingleCriteria implements Criteria
{

    /**
     * @param $persons
     * @return Person[]
     */
    public function filter($persons)
    {
        $result = [];
        foreach ($persons as $person) {
            if (strtolower($person->maritalStatus) === 'single') {
                $result[] = $person;
            }
        }
        return $result;
    }
}
Bin_x

  连接多个过滤器的类:

class AndCriteria implements Criteria
{

    /**
     * @var Criteria
     */
    private $_criteria1;
    /**
     * @var Criteria
     */
    private $_criteria2;

    function __construct($criteria1, $criteria2)
    {
        $this->_criteria1 = $criteria1;
        $this->_criteria2 = $criteria2;
    }

    /**
     * @param $persons Person[]
     * @return Person[]
     */
    public function filter($persons)
    {
        return $this->_criteria2->filter($this->_criteria1->filter($persons));
    }
}

class OrCriteria implements Criteria
{

    /**
     * @var Criteria
     */
    private $_criteria1;
    /**
     * @var Criteria
     */
    private $_criteria2;

    function __construct($criteria1, $criteria2)
    {
        $this->_criteria1 = $criteria1;
        $this->_criteria2 = $criteria2;
    }

    /**
     * @param $persons Person[]
     * @return Person[]
     */
    public function filter($persons)
    {
        $result1 = $this->_criteria1->filter($persons);
        $result2 = $this->_criteria2->filter($persons);
        foreach ($result2 as $person) {
            if (!in_array($person, $result1)) {
                $result1[] = $person;
            }
        }
        return $result1;
    }
}
Bin_x

  应用:

$data=[
    new Person("Robert", "Male", "Single"),
    new Person("John", "Male", "Married"),
    new Person("Laura", "Female", "Married"),
    new Person("Diana", "Female", "Single"),
    new Person("Mike", "Male", "Single"),
    new Person("Bobby", "Male", "Single")
];

$maleCriteria=new MaleCriteria();
$femaleCriteria=new FemaleCriteria();
$singleCriteria=new SingleCriteria();
$singleMaleCriteria=new AndCriteria($singleCriteria,$maleCriteria);
$singleMaleCriteriaOrFemaleCriteria=new OrCriteria($femaleCriteria,$singleMaleCriteria);

print_r($singleMaleCriteriaOrFemaleCriteria->filter($data));
Bin_x

 

posted @ 2017-05-11 17:10  Bin_x  阅读(209)  评论(0编辑  收藏  举报