设计模式-过滤器模式C++

一、简介

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

二、过滤器模式实例

实例介绍

假如某地政府为了帮助无业人员就业,统计了一批36岁市民的就业情况。政府拿到名单后,过滤出无业人员帮助就业。

为了完成这个项目,我们需要建造:

1)人员信息类 Person;

2)标准抽象类 Criteria,提供按照某标准过滤的接口 meetCriteria;

3)标准具体类,继承Criteria,定义不同的过滤标准,实现meetCriteria接口;

代码实现

1)人员信息类 Person

class Person
{
public:
	Person(string name, int age, string gdr, string work)
		:_name(name)
		, _age(age)
		, _gender(gdr)
		, _work(work) {}
	~Person() {}

	void show()
	{
		cout << "**********档案记录***********" << endl;
		cout << "姓名:" <<_name << endl;
		cout << "性别:" << _gender << endl;
		cout << "工作:" << _work << endl;
	}

public:
	string _name;		   //姓名
	int _age;		       //年龄
	string _gender;		   //性别
	string _work;		   //工作
};

2)标准抽象类 Criteria,提供按照某标准过滤的接口 meetCriteria;

class Criteria
{
public:
	//定义过滤器接口:按照某一标准过滤出对象指针列表,这一标准由继承了Criteria的实体类具体定义
	virtual vector<Person*> meetCriteria(vector<Person*> all) = 0;
};

3)标准具体类,继承Criteria,定义不同的过滤标准,实现meetCriteria接口;

其中定义了过滤女性男性、和无业者的类,并且提供了这两种可以提供组合2个过滤器服务的过滤器。

//女性过滤器
class CriteriaFemale : public Criteria
{
	vector<Person*> meetCriteria(vector<Person*> allPerson)
	{
		vector<Person*> per;
		for (auto it: allPerson)
		{
			if ("女" == it->_gender)
			{
				per.push_back(it);
			}
		}
		return per;
	}
};

//男性过滤器
class CriteriaMale : public Criteria
{
	vector<Person*> meetCriteria(vector<Person*> allPerson)
	{
		vector<Person*> per;
		for (auto it : allPerson)
		{
			if ("男" == it->_gender)
			{
				per.push_back(it);
			}
		}
		return per;
	}
};

//无业者过滤器
class CriteriaUnemployed : public Criteria
{
	vector<Person*> meetCriteria(vector<Person*> allPerson)
	{
		vector<Person*> per;
		for (auto it : allPerson)
		{
			if ("" == it->_work)
			{
				per.push_back(it);
			}
		}
		return per;
	}
};
//逻辑关系:与 的过滤器
class AndCriteria :public Criteria
{
public:
	AndCriteria(Criteria *p1, Criteria *p2)
		:_pCriteria1(p1)
		,_pCriteria2(p2) {}
	~AndCriteria()
	{
		if (nullptr != _pCriteria1)
		{
			delete _pCriteria1;
			_pCriteria1 = nullptr;
		}
		if (nullptr != _pCriteria2)
		{
			delete _pCriteria2;
			_pCriteria2 = nullptr;
		}
	}
	
	vector<Person*> meetCriteria(vector<Person*> allPerson)
	{
		vector<Person*> per;
		if (nullptr == _pCriteria1 || nullptr == _pCriteria2)
		{
			return per;
		}
		//先以标准1过滤
		per = _pCriteria1->meetCriteria(allPerson);
		//再以标准2过滤标准1的结果
		per = _pCriteria2->meetCriteria(per);

		return per;
	}

private:
	Criteria *_pCriteria1;
	Criteria *_pCriteria2;
};
//逻辑关系:或 的过滤器
class OrCriteria :public Criteria
{
public:
	OrCriteria(Criteria *p1, Criteria *p2)
		:_pCriteria1(p1)
		, _pCriteria2(p2) {}

	~OrCriteria()
	{
		if (nullptr != _pCriteria1)
		{
			delete _pCriteria1;
			_pCriteria1 = nullptr;
		}
		if (nullptr != _pCriteria2)
		{
			delete _pCriteria2;
			_pCriteria2 = nullptr;
		}
	}

	vector<Person*> meetCriteria(vector<Person*> allPerson)
	{
		vector<Person*> per;
		if (nullptr == _pCriteria1 || nullptr == _pCriteria2)
		{
			return per;
		}
		//以标准1和标准2分别过滤整个样本
		per = _pCriteria1->meetCriteria(allPerson);
		vector<Person*> per2;
		per2 = _pCriteria2->meetCriteria(allPerson);
		//合并两个过滤结果
		for (auto it:per2)
		{
			per.push_back(it);
		}

		return per;
	}

private:
	Criteria *_pCriteria1;
	Criteria *_pCriteria2;
};

4)使用

int main(int argc, char *argv[])
{
	Person p1("A", 36, "男", "法官");
	Person p2("B", 36, "男", "教师");
	Person p3("C", 36, "男", "农民");
	Person p4("D", 36, "男", "");
	Person p5("E", 36, "男", "");
	Person p6("F", 36, "男", "");
	Person p7("G", 36, "女", "保洁");
	Person p8("H", 36, "女", "医生");
	Person p9("J", 36, "女", "工程师");
	Person p10("K", 36, "女", "");
	Person p11("L", 36, "女", "");
	vector< Person*> allPerson;
	allPerson.push_back(&p1);
	allPerson.push_back(&p2);
	allPerson.push_back(&p3);
	allPerson.push_back(&p4);
	allPerson.push_back(&p5);
	allPerson.push_back(&p6);
	allPerson.push_back(&p7);
	allPerson.push_back(&p8);
	allPerson.push_back(&p9);
	allPerson.push_back(&p10);
	allPerson.push_back(&p11);
	
	//女性过滤器
	CriteriaFemale *female = new CriteriaFemale();
	//男性过滤器
	CriteriaMale *male = new CriteriaMale();
	//无业过滤器
	CriteriaUnemployed *unemployed = new CriteriaUnemployed();

	//女性无业者列表
	AndCriteria *and1 = new AndCriteria(female, unemployed);
	vector< Person*> per = and1->meetCriteria(allPerson);
	cout << "女性无业者列表 :" << endl;
	for (auto it : per)
	{
		it->show();
	}

	//男性无业者列表
	AndCriteria *and2 = new AndCriteria(male, unemployed);
	per = and2->meetCriteria(allPerson);
	cout << endl << "男性无业者列表 :" << endl;
	for (auto it : per)
	{
		it->show();
	}

	system("pause");
	return 0;
}

5)输出

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值