2010-03-31 160 views
5

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

可以说我有一个有说明字段或属性的类。我需要过滤器来从这个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(); 
    } 
} 
+0

[滤波器设计图案示例](http://www.singhajit.com/filter-design-pattern/) – 2016-10-11 06:20:06

回答

3

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

如果这不是你正在寻找的,也许decorator pattern会更合适。这将允许您打包过滤器并在需要时应用多个过滤器。

+0

我觉得装饰不是我想要的。因为无论何时我需要应用新的过滤器,我都必须手动将其添加到要装饰的对象中。我需要更抽象的方式来做到这一点。 – Tarik 2010-03-31 09:10:01

+0

我不确定。使用装饰器,您可以将不同的过滤器堆叠在另一个过滤器中。所以当你调用最外层过滤器的过滤方法时,他会应用封装的过滤器。这与在Daren例子中循环遍历所有过滤器类似。 http://www.dofactory.com/Patterns/PatternDecorator.aspx#_self1 – FrenchData 2010-04-01 11:35:44

1

对我来说这听起来像Strategy模式。

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

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

注:GetFilteredDescription是你的类的成员函数。

1

您可以使用下面的模式:

  • 策略模式不同的过滤器类型
  • 链责任的滤光器叠层(您可以在多任务环境在这里添加命令模式不同的链,或者你可以实现基于优先级的链等)
  • 构建或抽象工厂的过滤器实例创作。
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)); 

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

为了总结的东西了,我建议你的子类列表:

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

实际上,它被称为策略模式tho :)在C#委托用于策略模式,但我喜欢你的例子。谢谢。 – Tarik 2010-03-31 09:11:50

+0

但是你有点不同,因为你没有改变这个策略,你只是运行所有应用的代表,这是我想要的。 – Tarik 2010-03-31 09:14:01

+0

而且我应该将方法放在列表中吗?我不能+向代理添加更多方法吗? – Tarik 2010-03-31 17:09:53