views:

95

answers:

5

Hi people,

I am thinking to create a filter object which filters and delete everything like html tags from a context. But I want it to be independent which means the design pattern I can apply will help me to add more filters in the future without effecting the current codes. I thought Abstract Factory but it seems it ain't gonna work out the way I want. So maybe builder but it looks same. I don't know I am kinda confused, some one please recommend me a design pattern which can solve my problem but before that let me elaborate the problem a little bit.

Lets say I have a class which has Description field or property what ever. And I need filters which remove the things I want from this Description property. So whenever I apply the filter I can add more filter in underlying tier. So instead of re-touching the Description field, I can easily add more filters and all the filters will run for Description field and delete whatever they are supposed to delete from the Description context.

I hope I could describe my problem. I think some of you ran into the same situation before.

Thanks in advance...

Edit :

I actually want to create filters as types/classes instead of regular methods or whatever. Like :

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.
   }
}

At this point if I want to apply Abstract Factory which would be meaningless or Builder as well. Because I don't want a particular thing, I need all of them kinda.

Thanks for your answers by the way.

Edit 2 - Possible Answer for Me

Okay lets think about strategy pattern with interfaces rather than delegates.

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();
   }
}
+3  A: 

Have you looked at the strategy pattern? It allows you to swap algorithms.

If that is not what you are looking for, perhaps the decorator pattern will be more suitable. This will allow you to wrap filters and apply multiple ones if needed.

Oded
I think decorator is not what I want. Because whenever I need to apply new filter I have to go and add this manually into the object that I want to decorate. I need more abstract way to do it.
Braveyard
I'm not sure. With the decorator you can just pile the different filter one in another. So when you call the filter method of most outer filter, he will apply the encapsulated filters. This would be similar to looping through all filters as in Daren's exemple. http://www.dofactory.com/Patterns/PatternDecorator.aspx#_self1
FrenchData
+1  A: 

To me this sounds like the Strategy pattern.

Could be something like this (the code is in VB):

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

Note: the GetFilteredDescription is member function of your class.

Ando
+1  A: 

You can use below patterns:

  • Strategy Pattern for different Filter types
  • Chain of Responsibility for your filter stack (You can add Command Pattern here for different chains in a multitasking environment, or you can implement priority based chain or so on )
  • Builder or Abstract Factory for Filter instance creations.
baris_a
+1  A: 

What about Provider pattern? http://msdn.microsoft.com/en-us/library/ms972319.aspx

It is similar to Strategy, and is used in Microsoft products thoroughly.

Lex Li
+3  A: 

Why don't you just go light weight: Define your filter as a Func<string, string>. If you keep these in a collection (List<Func<string, string>>), you can just do:

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

You can also use Linq to shorten the above loop:

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

This way, you don't have to define a class hierarchy for filtering. This is good for the environment, since we will be running out of classes and namespaces very soon!

To wrap things up, I suggest you subclass List:

public class FilterCollection : List<Func<string, string>>
{
    public string Filter(string text)
    {
        return this.Aggregate(text, (seed, func) => func(seed));
    }
}
Daren Thomas
Well actually it is called Strategy pattern tho :) in C# delegates are used for strategy pattern but I like your example. Thanks.
Braveyard
But yours is little bit different since you are not changing the strategy you are simply running all the applied delegates which is kinda what I want.
Braveyard
And should I keep the methods in a List?Can't I += to add more method to Delegate?
Braveyard
You can += to add more methods to a delegate, but all you can then do is call them all at once (as far as I can tell from my trusty reference). So, no. Keep them in a list, but see the subclass above.
Daren Thomas