结构型模式 过滤器模式

结构型模式 过滤器模式

过滤器模式

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。

实现

我们将创建一个 Person 对象、Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表。CriteriaPatternDemo,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Person 对象的列表。

/**
 * 结构型模式 过滤器模式
 * 使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。
 *
 */

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <list>

class Person
{
public:
    Person(std::string name, std::string gender, std::string maritalStatus)
    {
        m_name = name;
        m_gender = gender;
        m_maritalStatus = maritalStatus;
    }
    std::string getName()
    {
        return m_name;
    }
    std::string getGender()
    {
        return m_gender;
    }
    std::string getMaritalStatus()
    {
        return m_maritalStatus;
    }

private:
    std::string m_name;
    std::string m_gender;
    std::string m_maritalStatus;
};

static void printPersons(std::list<Person> *persons)
{
    for (std::list<Person>::iterator it = persons->begin(); it != persons->end(); it++)
    {
        std::cout << "Person: [ Name: " << it->getName() << " Gender: " << it->getGender() << " MaritalStatus: " << it->getMaritalStatus() << " ]"<< std::endl;
    }
}

class ICriteria
{
public:
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) = 0;
    virtual ~ICriteria() {}
};

class CriteriaMale: public ICriteria
{
public:
    CriteriaMale()
    {
        plist = new std::list<Person>();
        plist->clear();
    }
    ~CriteriaMale()
    {
        plist->clear();
        delete plist;
        plist = nullptr;
    }
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) override
    {
        plist->clear();
        for (std::list<Person>::iterator it = persons->begin(); it != persons->end(); it++)
        {
            if ((*it).getGender() == "male")
            {
                plist->push_back(*it);
            }
        }
        return plist;
    }
private:
    std::list<Person> * plist;
};

class CriteriaFemale: public ICriteria
{
public:
    CriteriaFemale()
    {
        plist = new std::list<Person>();
        plist->clear();
    }
    ~CriteriaFemale()
    {
        plist->clear();
        delete plist;
        plist = nullptr;
    }
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) override
    {
        plist->clear();
        for (std::list<Person>::iterator it = persons->begin(); it != persons->end(); it++)
        {
            if ((*it).getGender() == "female")
            {
                plist->push_back(*it);
            }
        }
        return plist;
    }
private:
    std::list<Person> * plist;
};

class CriteriaSingle: public ICriteria
{
public:
    CriteriaSingle()
    {
        plist = new std::list<Person>();
        plist->clear();
    }
    ~CriteriaSingle()
    {
        plist->clear();
        delete plist;
        plist = nullptr;
    }
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) override
    {
        plist->clear();
        for (std::list<Person>::iterator it = persons->begin(); it != persons->end(); it++)
        {
            if ((*it).getMaritalStatus() == "single")
            {
                plist->push_back(*it);
            }
        }
        return plist;
    }
private:
    std::list<Person> * plist;
};

class AndCriteria: public ICriteria
{
public:
    AndCriteria(ICriteria *pcriteria1, ICriteria *pcriteria2)
    {
        this->pcriteria1 = pcriteria1;
        this->pcriteria2 = pcriteria2;
    }
    ~AndCriteria()
    {
        this->pcriteria1 = nullptr;
        this->pcriteria2 = nullptr;
    }
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) override
    {
        return pcriteria2->MeetCriteria(pcriteria1->MeetCriteria(persons));
    }
private:
    class ICriteria *pcriteria1;
    class ICriteria *pcriteria2;
};

class OrCriteria: public ICriteria
{
public:
    OrCriteria(ICriteria *pcriteria1, ICriteria *pcriteria2)
    {
        this->pcriteria1 = pcriteria1;
        this->pcriteria2 = pcriteria2;
    }
    ~OrCriteria()
    {
        this->pcriteria1 = nullptr;
        this->pcriteria2 = nullptr;
    }
    virtual std::list<Person> * MeetCriteria(std::list<Person> * persons) override
    {
        std::list<Person> * temp1 = pcriteria1->MeetCriteria(persons);
        std::list<Person> * temp2 = pcriteria2->MeetCriteria(persons);
        bool flag = true;
        for (std::list<Person>::iterator it1 = temp1->begin(); it1 != temp1->end(); it1++)
        {
            flag = true;
            for (std::list<Person>::iterator it2 = temp2->begin(); it2 != temp2->end(); it2++)
            {
                if ( ((*it1).getName() == (*it2).getName() &&
                        (*it1).getGender() == (*it2).getGender() &&
                        (*it1).getMaritalStatus() == (*it2).getMaritalStatus() ) )
                {
                    flag = false;
                    break;
                }
            }
            if ( flag )
            {
                temp2->push_back(*it1);
            }
        }
        return temp2;
    }
private:
    class ICriteria *pcriteria1;
    class ICriteria *pcriteria2;
};

void mytest()
{
    std::list<Person> *persons = new std::list<Person>;
    persons->push_back(Person("Robert","male", "single"));
    persons->push_back(Person("John","male", "married"));
    persons->push_back(Person("Laura","female", "married"));
    persons->push_back(Person("Diana","female", "single"));
    persons->push_back(Person("Mike","male", "single"));
    persons->push_back(Person("Bobby","male", "single"));

    ICriteria * male = new CriteriaMale();
    ICriteria * female = new CriteriaFemale();
    ICriteria * single = new CriteriaSingle();
    ICriteria * singleMale = new AndCriteria(single, male);
    ICriteria * singleOrFemale = new OrCriteria(single, female);

    std::cout << "Males: "  << std::endl;
    printPersons(male->MeetCriteria(persons));

    std::cout << "Females: "  << std::endl;
    printPersons(female->MeetCriteria(persons));

    std::cout << "Single: "  << std::endl;
    printPersons(single->MeetCriteria(persons));

    std::cout << "Single Males: "  << std::endl;
    printPersons(singleMale->MeetCriteria(persons));

    std::cout << "Single Or Females: "  << std::endl;
    printPersons(singleOrFemale->MeetCriteria(persons));

    persons->clear();
    delete persons;
    persons = nullptr;
    delete male;
    male = nullptr;
    delete female;
    female = nullptr;
    delete single;
    single = nullptr;
    delete singleMale;
    singleMale = nullptr;
    delete singleOrFemale;
    singleOrFemale = nullptr;

    return;
}


int main()
{
    mytest();

    system("pause");
    return 0;
}

 输出结果:

Males:
Person: [ Name: Robert Gender: male MaritalStatus: single ]
Person: [ Name: John Gender: male MaritalStatus: married ]
Person: [ Name: Mike Gender: male MaritalStatus: single ]
Person: [ Name: Bobby Gender: male MaritalStatus: single ]
Females:
Person: [ Name: Laura Gender: female MaritalStatus: married ]
Person: [ Name: Diana Gender: female MaritalStatus: single ]
Single:
Person: [ Name: Robert Gender: male MaritalStatus: single ]
Person: [ Name: Diana Gender: female MaritalStatus: single ]
Person: [ Name: Mike Gender: male MaritalStatus: single ]
Person: [ Name: Bobby Gender: male MaritalStatus: single ]
Single Males:
Person: [ Name: Robert Gender: male MaritalStatus: single ]
Person: [ Name: Mike Gender: male MaritalStatus: single ]
Person: [ Name: Bobby Gender: male MaritalStatus: single ]
Single Or Females:
Person: [ Name: Laura Gender: female MaritalStatus: married ]
Person: [ Name: Diana Gender: female MaritalStatus: single ]
Person: [ Name: Robert Gender: male MaritalStatus: single ]
Person: [ Name: Mike Gender: male MaritalStatus: single ]
Person: [ Name: Bobby Gender: male MaritalStatus: single ]
原文地址:https://www.cnblogs.com/lsgxeva/p/7780176.html