一、产生背景
我们有一堆“人”的对象,我们应该怎么选择出其中的男性、女性或者其他类型的呢?这时候我们可以用过滤器模式
二、通常做法
我们将创建一个 Person 对象、Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表。CriteriaPattern,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Person 对象的列表。
三、实例
1、创建person类
namespace FilterPattern
{
public class Person
{ private string name;
private string gender;
private string maritalStatus; public Person(string name, string gender, string maritalStatus)
{
this.name = name;
this.gender = gender;
this.maritalStatus = maritalStatus;
} public string GetName()
{
return name;
}
public string GetGender()
{
return gender;
}
public string GetMaritalStatus()
{
return maritalStatus;
}
}
}
2、建立筛选标准
namespace FilterPattern
{
public interface ICriteria
{
List<Person> MeetCriteria(List<Person> persons);
}
}
public class CriteriaMale : ICriteria
{
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> malePersons = new List<Person>();
foreach (Person p in persons)
{
if (p.GetGender().Equals("Male"))
malePersons.Add(p);
}
return malePersons;
}
} public class CriteriaFeMale : ICriteria
{
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> femalePersons = new List<Person>();
foreach (Person p in persons)
{
if (p.GetGender().Equals("Female"))
femalePersons.Add(p);
}
return femalePersons;
}
} public class CriteriaSingle : ICriteria
{
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> singlePersons = new List<Person>();
foreach (Person p in persons)
{
if (p.GetGender().Equals("Single"))
singlePersons.Add(p);
}
return singlePersons;
}
} public class AndCriteria : ICriteria
{
private ICriteria criteria;
private ICriteria otherCriteria;
public AndCriteria(ICriteria criteria, ICriteria otherCriteria)
{
this.criteria = criteria;
this.otherCriteria = otherCriteria;
} public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> firstCriteriaPersons = criteria.MeetCriteria(persons);
return otherCriteria.MeetCriteria(firstCriteriaPersons);
}
} public class OrCriteria : ICriteria
{
private ICriteria criteria;
private ICriteria otherCriteria;
public OrCriteria(ICriteria criteria, ICriteria otherCriteria)
{
this.criteria = criteria;
this.otherCriteria = otherCriteria;
} public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> firstCriteriaItems = criteria.MeetCriteria(persons);
List<Person> otherCriteriaItems = otherCriteria.MeetCriteria(persons); foreach (Person person in otherCriteriaItems)
{
if (!firstCriteriaItems.Contains(person))
{
firstCriteriaItems.Add(person);
}
}
return firstCriteriaItems;
}
}
3、客户端调用
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>(); persons.Add(new Person("Robert", "Male", "Single"));
persons.Add(new Person("John", "Male", "Married"));
persons.Add(new Person("Laura", "Female", "Married"));
persons.Add(new Person("Diana", "Female", "Single"));
persons.Add(new Person("Mike", "Male", "Single"));
persons.Add(new 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); Console.WriteLine("Males: ");
PrintPersons(male.MeetCriteria(persons)); Console.WriteLine("\nFemales: ");
PrintPersons(female.MeetCriteria(persons)); Console.WriteLine("\nSingle Males: ");
PrintPersons(singleMale.MeetCriteria(persons)); Console.WriteLine("\nSingle Or Females: ");
PrintPersons(singleOrFemale.MeetCriteria(persons)); Console.ReadLine();
} public static void PrintPersons(List<Person> persons)
{
foreach (Person person in persons)
{
Console.WriteLine("Person : [ Name : " + person.GetName()
+ ", Gender : " + person.GetGender()
+ ", Marital Status : " + person.GetMaritalStatus()
+ " ]");
}
}
}
四、设计模式分析
优点:结构清晰,解耦合
缺点:使类型编的复杂