过滤器模式
过滤器模式也称作标准模式,可以根据不同标准来分别或统一过滤对象。该模式属于结构型模式。
本例中被过滤的对象是Commodity(商品),该对象包含商品价格和商品等级。此外还有一个过滤器接口,包含与、或运算,并且实现该接口。
过滤对象:
1 /// <summary> 2 /// 商品类,被过滤的对象 3 /// </summary> 4 public class Commodity 5 { 6 private int m_price; 7 private int m_grades; 8 9 public int Price 10 { 11 set; get; 12 } 13 14 public int Grades 15 { 16 set; get; 17 } 18 }
过滤条件接口:
1 /// <summary> 2 /// 过滤器接口 3 /// </summary> 4 public interface IFilter<T> where T : class 5 { 6 /// <summary> 7 /// 过滤器 8 /// </summary> 9 /// <param name="commodities"></param> 10 /// <returns></returns> 11 List<T> Filter(List<T> list, Func<T, bool> func); 12 13 /// <summary> 14 /// And 15 /// </summary> 16 /// <param name="list"></param> 17 /// <param name="func1"></param> 18 /// <param name="func2"></param> 19 /// <returns></returns> 20 List<T> And(List<T> list, Func<T, bool> func1, Func<T, bool> func2); 21 22 /// <summary> 23 /// Or 24 /// </summary> 25 /// <param name="list"></param> 26 /// <param name="func1"></param> 27 /// <param name="func2"></param> 28 /// <returns></returns> 29 List<T> Or(List<T> list, Func<T, bool> func1, Func<T, bool> func2); 30 }
过滤条件实现:
1 public class StandardFilter<T> : IFilter<T> where T : class 2 { 3 public List<T> Filter(List<T> list, Func<T, bool> func) 4 { 5 List<T> ts = new List<T>(); 6 foreach (var item in list) 7 { 8 if (func.Invoke(item)) 9 { 10 ts.Add(item); 11 } 12 } 13 return ts; 14 } 15 16 public List<T> And(List<T> list, Func<T, bool> func1, Func<T, bool> func2) 17 { 18 List<T> ts = new List<T>(); 19 foreach (var item in list) 20 { 21 if (func1.Invoke(item) && func2.Invoke(item)) 22 { 23 ts.Add(item); 24 } 25 } 26 return ts; 27 } 28 29 public List<T> Or(List<T> list, Func<T, bool> func1, Func<T, bool> func2) 30 { 31 List<T> ts = new List<T>(); 32 foreach (var item in list) 33 { 34 if (func1.Invoke(item) || func2.Invoke(item)) 35 { 36 ts.Add(item); 37 } 38 } 39 return ts; 40 } 41 }
客户端:
1 static void Main(string[] args) 2 { 3 List<Commodity> commodities = new List<Commodity>(); 4 for (int i = 0; i < 2; i++) 5 { 6 Commodity commodity = new Commodity(); 7 commodity.Price = i; 8 commodity.Grades = i; 9 commodities.Add(commodity); 10 } 11 12 StandardFilter<Commodity> standardFilter = new StandardFilter<Commodity>(); 13 var list0 = standardFilter.Filter(commodities, (item) => { return item.Price == 1; }); 14 var list1 = standardFilter.And(commodities, (item) => { return item.Price == 1; }, (item) => { return item.Grades == 11; }); 15 var list2 = standardFilter.Or(commodities, (item) => { return item.Price == 1; }, (item) => { return item.Grades == 11; }); 16 Console.WriteLine(list0.Any()); 17 Console.WriteLine(list1.Any()); 18 Console.WriteLine(list2.Any()); 19 20 Console.ReadLine(); 21 }
本文使用匿名函数来过滤对象,实则多此一举,因为条件过滤可以直接使用C#的lambda表达式来实现。