過濾器模式通過使用不同的過濾標準來篩選數據,解耦了多個數據源的數據篩選操作。 介紹 過濾器模式屬於結構型模式,它通過將多個不同的過濾標準結合起來從而達到一個統一的過濾標準,使具體的過濾對上層隔離。 類圖描述 由上圖可知, ICriteria 定義了過濾介面,然後 CriteriaMale 、 Cri ...
過濾器模式通過使用不同的過濾標準來篩選數據,解耦了多個數據源的數據篩選操作。
介紹
過濾器模式屬於結構型模式,它通過將多個不同的過濾標準結合起來從而達到一個統一的過濾標準,使具體的過濾對上層隔離。
類圖描述
由上圖可知,ICriteria 定義了過濾介面,然後 CriteriaMale 、CriteriaSingle、CriteriaFemale 為具體的底層數據過濾,接著定義 AndCriteria 和 OrCriteria 為組裝數據過濾。最後上層直接調用他們這兩個即可。
代碼實現
1、定義實體類
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() => name;
public string GetGender() => gender;
public string GetMaritalStatus() => maritalStatus;
}
1、定義過濾介面
public interface ICriteria
{
IEnumerable<Person> MeetCriteria(IEnumerable<Person> persons);
}
2、實現過濾介面
public class CriteriaFemale : ICriteria
{
public IEnumerable<Person> MeetCriteria(IEnumerable<Person> persions)
{
List<Person> femalePersons = new List<Person>();
femalePersons.AddRange(persions.Where(p => p.GetGender() == "FEMALE"));
return femalePersons;
}
}
public class CriteriaMale : ICriteria
{
public IEnumerable<Person> MeetCriteria(IEnumerable<Person> persions)
{
List<Person> malePersons = new List<Person>();
malePersons.AddRange(persions.Where(p => p.GetGender() == "MALE"));
return malePersons;
}
}
public class CriteriaSingle : ICriteria
{
public IEnumerable<Person> MeetCriteria(IEnumerable<Person> persons)
{
List<Person> malePersons = new List<Person>();
malePersons.AddRange(persons.Where(p => p.GetMaritalStatus() == "SINGLE"));
return malePersons;
}
}
3、組裝過濾器
public class AndCriteria : ICriteria
{
private ICriteria criteria;
private ICriteria otherCriteria;
public AndCriteria(ICriteria criteria,ICriteria otherCriteria)
{
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
public IEnumerable<Person> MeetCriteria(IEnumerable<Person> persions)
{
IEnumerable<Person> firstCriteriaPersons = criteria.MeetCriteria(persions);
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 IEnumerable<Person> MeetCriteria(IEnumerable<Person> persions)
{
List<Person> firstCriteriaItems = criteria.MeetCriteria(persions).ToList();
IEnumerable<Person> otherCriteriaItems = otherCriteria.MeetCriteria(persions);
foreach (var person in otherCriteriaItems)
{
if (!firstCriteriaItems.Contains(person))
{
firstCriteriaItems.Add(person);
}
}
return firstCriteriaItems;
}
}
4、上層調用
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.AddRange(new[] {
new Person("Robert", "MALE", "SINGLE"),
new Person("John", "MALE", "MARRIED"),
new Person("Laura", "FEMALE", "MARRIED"),
new Person("Diana", "FEMALE", "SINGLE"),
new Person("Mike", "MALE", "SINGLE"),
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.ReadKey();
}
private static void PrintPersons(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
Console.WriteLine($"Person [Name:{person.GetName()},Gender:{person.GetGender()},Marital Status:{person.GetMaritalStatus()}]");
}
}
}
總結
在實際開發過程中,如果遇到多個過濾標準的話,可以嘗試通過使用過濾器模式來將多個不同的過濾標準組合起來,使上層調用達到統一,底層篩選被隔離。