结构型模式 过滤器模式
过滤器模式
过滤器模式(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 ]