天天看點

C++設計模式:過濾器模式

作者:QT進階進階

過濾器模式

過濾器模式(Filter Pattern),又叫标準模式(Criteria Pattern),是一種結構型模式,通過結合多個标準來獲得單一标準。

這種設計模式允許開發人員使用不同的标準來過濾一組對象,通過邏輯運算以解耦的方式把它們連接配接起來。

使用場景

當你在一個很龐大的資料量中查找一些東西時,可以使用過濾器模式制定過濾規則,然後根據指定的标準進行過濾,得到符合條件的資料。

優缺點

優點:

1、展現了各功能子產品的“黑盤”特性及高内聚、低耦合的特點。

2、可以将整個系統的輸入,輸出行為看成是多個過濾器行為的簡單合成。

3、支援軟體功能子產品的重用。

4、便于系統維護:新的過濾器可以添加到現有系統中來,舊的可以由改進的過濾器替換。

5、支援某些特定的分析,如吞吐量計算、死鎖檢測等。

6、支援并行操作,每個過濾器可以作為一個單獨的任務完成。

缺點:

1、通常導緻系統處理過程的成批操作。

2、需要設計者協調兩個相對獨立但又存在關系的資料流。

3、可能需要每個過濾器自己完成資料解析和合成工作(如加密和解密),進而導緻系統性能下降,并增加了過濾器具體實作的複雜性。

注意事項

1、建構過濾規則時不要太繁瑣。

2、注意區分過濾和攔截的功能差異。

UML結構圖

C++設計模式:過濾器模式

代碼實作

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
           

繼續閱讀