過濾器模式
過濾器模式(Filter Pattern),又叫标準模式(Criteria Pattern),是一種結構型模式,通過結合多個标準來獲得單一标準。
這種設計模式允許開發人員使用不同的标準來過濾一組對象,通過邏輯運算以解耦的方式把它們連接配接起來。
使用場景
當你在一個很龐大的資料量中查找一些東西時,可以使用過濾器模式制定過濾規則,然後根據指定的标準進行過濾,得到符合條件的資料。
優缺點
優點:
1、展現了各功能子產品的“黑盤”特性及高内聚、低耦合的特點。
2、可以将整個系統的輸入,輸出行為看成是多個過濾器行為的簡單合成。
3、支援軟體功能子產品的重用。
4、便于系統維護:新的過濾器可以添加到現有系統中來,舊的可以由改進的過濾器替換。
5、支援某些特定的分析,如吞吐量計算、死鎖檢測等。
6、支援并行操作,每個過濾器可以作為一個單獨的任務完成。
缺點:
1、通常導緻系統處理過程的成批操作。
2、需要設計者協調兩個相對獨立但又存在關系的資料流。
3、可能需要每個過濾器自己完成資料解析和合成工作(如加密和解密),進而導緻系統性能下降,并增加了過濾器具體實作的複雜性。
注意事項
1、建構過濾規則時不要太繁瑣。
2、注意區分過濾和攔截的功能差異。
UML結構圖
代碼實作
person.h
建構類 Person,可輸出自己的屬性,判斷是否在一個數組中
QT開發交流+赀料君羊:714620761
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Person
{
public:
Person(string name, string gender, int age) : name(name), gender(gender), age(age) {}
void printf()
{
cout << "student name: " + name +
", gender: " + gender +
", age: " + std::to_string(age) << endl;
}
bool judVec(std::vector<Person*> vec)
{
auto iter = std::find(std::begin(vec), std::end(vec), this);
return (iter == std::end(vec));
}
string getName() { return this->name; }
string getGender() { return this->gender; }
int getAge() { return this->age; }
private:
string name;
string gender;
int age;
};
interface.h
建立抽象類 - 過濾器;建立實體類 - 過濾器、男性過濾器、女性過濾器、年齡過濾器
男性和年齡過濾器、女性或年齡過濾器
#include "person.h"
#include <algorithm>
class Criteria //基類-過濾器
{
public:
Criteria() {}
virtual ~Criteria() {}
virtual std::vector<Person *> filter(std::vector<Person *> vector) = 0;
};
class MaleCriteria: public Criteria //子類-男性過濾器
{
public:
std::vector<Person *> filter(std::vector<Person *> vector)
{
std::vector<Person *> result;
for(size_t i = 0; i < vector.size(); i++)
{
if(vector.at(i)->getGender() == "male")
{
result.push_back(vector.at(i));
}
}
return result;
}
};
class FemaleCriteria: public Criteria //子類-女性過濾器
{
public:
std::vector<Person *> filter(std::vector<Person *> vector)
{
std::vector<Person *> result;
for(size_t i = 0; i < vector.size(); i++)
{
if(vector.at(i)->getGender() == "female")
{
result.push_back(vector.at(i));
}
}
return result;
}
};
class AgeCriteria: public Criteria //子類-年齡過濾器
{
public:
std::vector<Person *> filter(std::vector<Person *> vector)
{
std::vector<Person *> result;
for(size_t i = 0; i < vector.size(); i++)
{
if(vector.at(i)->getAge() > 18) {
result.push_back(vector.at(i));
}
}
return result;
}
};
class AndCriteria: public Criteria //子類-與 && 過濾器
{
public:
AndCriteria(Criteria *firstCriteria, Criteria *secondCriteria): firstCriteria(firstCriteria), secondCriteria(secondCriteria) {}
std::vector<Person *> filter(std::vector<Person *> vector)
{
std::vector<Person *> firstvector = firstCriteria->filter(vector);
return secondCriteria->filter(firstvector);
}
private:
Criteria *firstCriteria;
Criteria *secondCriteria;
};
class OrCriteria: public Criteria //子類- 或 || 過濾器
{
public:
OrCriteria(Criteria *firstCriteria, Criteria *secondCriteria) : firstCriteria(firstCriteria), secondCriteria(secondCriteria) {}
std::vector<Person *> filter(std::vector<Person *> vector)
{
std::vector<Person *> firstvector = firstCriteria->filter(vector);
std::vector<Person *> secondvector = secondCriteria->filter(vector);
for(auto it: firstvector)
{
if (it->judVec(secondvector))
{
secondvector.push_back(it);
}
}
return secondvector;
}
private:
Criteria *firstCriteria;
Criteria *secondCriteria;
};
main.cpp
執行個體應用 - 根據不同的過濾規則擷取不同的資料
#include "interface.h"
int main()
{
std::vector<Person *> vector;
Person *stu1 = new Person("Billy", "male", 25);
Person *stu2 = new Person("Kitty", "female", 24);
Person *stu3 = new Person("Alice", "female", 23);
Person *stu4 = new Person("Ben", "male", 17);
Person *stu5 = new Person("Jeason", "male", 18);
Person *stu6 = new Person("Jon", "male", 20);
Person *stu7 = new Person("Miss", "female", 13);
Person *stu8 = new Person("Abbey", "female", 14);
vector.push_back(stu1);
vector.push_back(stu2);
vector.push_back(stu3);
vector.push_back(stu4);
vector.push_back(stu5);
vector.push_back(stu6);
vector.push_back(stu7);
vector.push_back(stu8);
Criteria *maleCriteria = new MaleCriteria();
Criteria *femaleCriteria = new FemaleCriteria();
Criteria *ageCriteria = new AgeCriteria();
Criteria *andCriteria = new AndCriteria(maleCriteria, ageCriteria);
Criteria *orCriteria = new OrCriteria(femaleCriteria, ageCriteria);
std::vector<Person *> malevector = maleCriteria->filter(vector);
std::vector<Person *> femalevector = femaleCriteria->filter(vector);
std::vector<Person *> agevector = ageCriteria->filter(vector);
std::vector<Person *> andvector = andCriteria->filter(vector);
std::vector<Person *> orvector = orCriteria->filter(vector);
cout << "male:" << endl;
for(auto it: malevector)
{
it->printf();
}
cout << endl << "female:" << endl;
for(auto it: femalevector)
{
it->printf();
}
cout << endl << "age > 18:" << endl;
for(auto it: agevector)
{
it->printf();
}
cout << endl << "male and age > 18:" << endl;
for(auto it: andvector)
{
it->printf();
}
cout << endl << "female or age > 18:" << endl;
for(auto it: orvector)
{
it->printf();
}
return 0;
}
運作結果:
male:
student name: Billy, gender: male, age: 25
student name: Ben, gender: male, age: 17
student name: Jeason, gender: male, age: 18
student name: Jon, gender: male, age: 20
female:
student name: Kitty, gender: female, age: 24
student name: Alice, gender: female, age: 23
student name: Miss, gender: female, age: 13
student name: Abbey, gender: female, age: 14
age > 18:
student name: Billy, gender: male, age: 25
student name: Kitty, gender: female, age: 24
student name: Alice, gender: female, age: 23
student name: Jon, gender: male, age: 20
male and age > 18:
student name: Billy, gender: male, age: 25
student name: Jon, gender: male, age: 20
female or age > 18:
student name: Billy, gender: male, age: 25
student name: Kitty, gender: female, age: 24
student name: Alice, gender: female, age: 23
student name: Jon, gender: male, age: 20
student name: Miss, gender: female, age: 13
student name: Abbey, gender: female, age: 14