一、产生背景
我们有一堆“人”的对象,我们应该怎么选择出其中的男性、女性或者其他类型的呢?这时候我们可以用过滤器模式
二、通常做法
我们将创建一个 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(" Females: "); PrintPersons(female.MeetCriteria(persons)); Console.WriteLine(" Single Males: "); PrintPersons(singleMale.MeetCriteria(persons)); Console.WriteLine(" Single 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() + " ]"); } } }
四、设计模式分析
优点:结构清晰,解耦合
缺点:使类型编的复杂