按照《POSA(面向模式的软件架构)》里的说法,管道过滤器(Pipe-And-Filter)应该属于架构模式,因为它通常决定了一个系统的基本架构。管道过滤器和生产流水线类似,在生产流水线上,原材料在流水线上经一道一道的工序,最后形成某种有用的产品。在管道过滤器中,数据经过一个一个的过滤器,最后得到需要的数据。
如果感觉抽象的话大家可以想想网上购物。在网上购物的时候一般都会用到搜索和过滤功能。多数网店不仅支持一次性过滤,而且还可以支持在过滤到的结果中层层过滤直至到找到你所钟爱的商品。本文就提出一种简化的实现。由于考虑到过滤器不仅可能是单一条件的,也可能是多个条件的组合。所以就通过Composite Pattern引入了Composite Filter以支持And、Or以及Not等组合条件过滤。类结构图如下:
代码实现如下:
namespace FilterDemo
{
public enum CATAGORY { Food, Drink, Cloth, Office, Other };
{
public enum CATAGORY { Food, Drink, Cloth, Office, Other };
public class Goods
{
public int Price { private set; get; }
public CATAGORY Category { private set; get; }
public Goods(CATAGORY category, int price)
{
Category = category;
Price = price;
}
}
{
public int Price { private set; get; }
public CATAGORY Category { private set; get; }
public Goods(CATAGORY category, int price)
{
Category = category;
Price = price;
}
}
public interface Filter
{
bool Match(Goods goods);
}
public class PriceRangeFilter : Filter
{
int min;
int max;
public PriceRangeFilter(int min, int max)
{
this.min = min;
this.max = max;
}
public bool Match(Goods goods)
{
return (goods.Price >= min && goods.Price <= max);
}
}
{
int min;
int max;
public PriceRangeFilter(int min, int max)
{
this.min = min;
this.max = max;
}
public bool Match(Goods goods)
{
return (goods.Price >= min && goods.Price <= max);
}
}
public class CategoryFilter : Filter
{
CATAGORY category;
public CategoryFilter(CATAGORY category)
{
this.category = category;
}
public bool Match(Goods goods)
{
return (goods.Category == category);
}
}
{
CATAGORY category;
public CategoryFilter(CATAGORY category)
{
this.category = category;
}
public bool Match(Goods goods)
{
return (goods.Category == category);
}
}
public class CompositeFilter : Filter
{
protected ArrayList filters = new ArrayList();
public void AddFilters( params Filter[] filters)
{
this.filters.AddRange(filters);
}
public void AddFilter(Filter filter)
{
this.filters.Add(filter);
}
public bool Match(Goods goods)
{
return false;
}
}
{
protected ArrayList filters = new ArrayList();
public void AddFilters( params Filter[] filters)
{
this.filters.AddRange(filters);
}
public void AddFilter(Filter filter)
{
this.filters.Add(filter);
}
public bool Match(Goods goods)
{
return false;
}
}
public class AddFilter : CompositeFilter
{
public bool Match(Goods goods)
{
foreach (Filter filter in filters)
{
if (!filter.Match(goods))
return false;
}
return true;
}
}
{
public bool Match(Goods goods)
{
foreach (Filter filter in filters)
{
if (!filter.Match(goods))
return false;
}
return true;
}
}
public class OrFilter : CompositeFilter
{
public bool Match(Goods goods)
{
foreach(Filter filter in filters)
{
if(filter.Match(goods))
return true;
}
return false;
}
}
}
{
public bool Match(Goods goods)
{
foreach(Filter filter in filters)
{
if(filter.Match(goods))
return true;
}
return false;
}
}
}
至此,Pipe-And-Filter模式的Filter部分设计已经完成。剩下的就是设计管道,并安装上述各种Filter。
转载于:https://blog.51cto.com/bj007/345677