过滤选项的设计模式建议

时间:2010-03-31 06:24:48

标签: c# .net design-patterns

我正在考虑创建一个过滤器对象,用于过滤和删除上下文中的html标记等所有内容。但我希望它是独立的,这意味着我可以应用的设计模式将帮助我在将来添加更多过滤器而不影响当前代码。我认为抽象工厂,但似乎它不会按照我想要的方式工作。也许建设者,但它看起来一样。我不知道我有点困惑,有人请推荐我一个可以解决我的问题的设计模式,但在此之前让我详细说明问题。

假设我有一个具有描述字段或属性的类。我需要过滤器从这个Description属性中删除我想要的东西。因此,每当我应用过滤器时,我都可以在基础层中添加更多过滤器。因此,我可以轻松添加更多过滤器,而不是重新触摸Description字段,所有过滤器都将针对Description字段运行,并从Description上下文中删除它们应删除的任何内容。

我希望我能描述一下我的问题。我想你们中的一些人之前遇到过同样的情况。

提前致谢...

修改:

我实际上想要将过滤器创建为类型/类而不是常规方法或其他。喜欢:

class TextFilter : IFilter
{
   private string something;
   public string Awesome {get;set;}
   public string FilterYo(string textFiltered)
   {
      // Do filtering
   }
}

class HtmlFilter : IFilter
{
   private string something;
   private string iGotSomething;
   public string Awesome {get;set;}
   public string FilterYo(string textFiltered)
   {
      // Do filtering
   }
}

class Main
{
   protected void Main(object sender, EventArgs e)
   { 
      InputClass input = new InputClass();
      string filtered = new StartFiltering().Filter(input.Description); // at this moment, my input class shouldn't know anything about filters or something. I don't know if it makes any sense but this is what in my mind.
   }
}

此时如果我想申请抽象工厂,这将是毫无意义的或生成器。因为我不需要特别的东西,所以我需要他们所有人。

顺便谢谢你的答案。

编辑2 - 我可能的答案

好吧,让我们考虑使用接口而不是委托的策略模式。

interface IFilter //Strategy interface
{
   string Filter(string text);
}

class LinkFilter:IFilter  //Strategy concrete class
{
   public string Filter(string text)
   {
     //filter link tags and return pure text;
   }
}

class PictureFilter:IFilter //Strategy concrete class
{
   public string Filter(string text)
   {
     //filter links and return pure text;
   } 
}

class Context
{
   private IFilter _filter;
   private string _text;
   public Context(IFilter filter,string text)
   {
      this._filter = filter;
      this._text = text;
   }

   public void UpdateFilter(IFilter filter)
   {
      this._filter = filter;
   }

   public string RunFilter()
   {

     this._text = _filter.Filter(this._text);
     return this._text;
   }
}

class MainProgram
{
   static void Main()
   {
      MyObject obj = new MyObject();
      LinkFilter lfilter = new LinkFilter();
      PictureFilter pfilter = new PictureFilter();
      Context con = new Context(lfilter,obj.Description);
      string desc = con.RunFilter();
      con.UpdateFilter(pfilter);
      desc = con.RunFilter();
   }
}

5 个答案:

答案 0 :(得分:8)

为什么不轻量一点:将过滤器定义为Func<string, string>。如果将它们保存在集合(List<Func<string, string>>)中,您可以这样做:

var text = myObject.DescriptionProperty
foreach (var func in myFuncList)
{
    text = func(text);
}

您也可以使用Linq缩短上述循环:

var text = myFuncList.Aggregate(text, (seed, func) => func(seed));

这样,您不必为过滤定义类层次结构。这对环境有好处,因为我们很快就会用完类和名称空间!

为了总结,我建议你继承List:

public class FilterCollection : List<Func<string, string>>
{
    public string Filter(string text)
    {
        return this.Aggregate(text, (seed, func) => func(seed));
    }
}

答案 1 :(得分:3)

你看过strategy pattern了吗?它允许您交换算法。

如果这不是你想要的,那么decorator pattern可能会更合适。这将允许您包装过滤器并在需要时应用多个过滤器。

答案 2 :(得分:1)

对我而言,这听起来像是Strategy模式。

可能是这样的(代码在VB中):

       Function GetFilteredDescription(ByVal iSpecificFilterFunction As AbstractFilterFunction) As Result
           Return iSpecificFilterFunction.Filter(Me.description)
       End Function

注意:GetFilteredDescription是您班级的成员函数。

答案 3 :(得分:1)

您可以使用以下模式:

  • 不同过滤器类型的策略模式
  • 您的过滤器堆栈的责任链(您可以在多任务环境中为不同的链添加命令模式,或者您可以实现基于优先级的链等)
  • 用于过滤器实例创建的构建器或抽象工厂。

答案 4 :(得分:1)

提供者模式怎么样? http://msdn.microsoft.com/en-us/library/ms972319.aspx

它类似于策略,并在Microsoft产品中得到彻底使用。