Рекомендации по шаблонам проектирования для опции фильтрации - PullRequest
5 голосов
/ 31 марта 2010

Я думаю создать объект фильтра, который фильтрует и удаляет все, как 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.
   }
}

На данный момент, если я хочу применить Abstract Factory, которая была бы бессмысленной, или Builder. Потому что я не хочу какой-то конкретной вещи, мне нужны все они вроде.

Спасибо за ваши ответы, кстати.

Редактировать 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 ]

8 голосов
/ 31 марта 2010

Почему бы вам просто не набрать вес: определите свой фильтр как 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));
    }
}
3 голосов
/ 31 марта 2010

Вы смотрели на шаблон стратегии ? Позволяет менять алгоритмы.

Если это не то, что вы ищете, возможно, подойдет шаблон декоратора . Это позволит вам обернуть фильтры и при необходимости применить несколько.

1 голос
/ 31 марта 2010

А как насчет шаблона провайдера? http://msdn.microsoft.com/en-us/library/ms972319.aspx

Он похож на стратегию и тщательно используется в продуктах Microsoft.

1 голос
/ 31 марта 2010

Вы можете использовать следующие шаблоны:

  • Шаблон стратегии для разных типов фильтров
  • Цепочка ответственности для вашего стека фильтров (здесь вы можете добавить шаблон команд для различных цепочек в многозадачной среде или реализовать цепочку на основе приоритетов или т.
  • Построитель или Абстрактная фабрика для создания экземпляров фильтра.
1 голос
/ 31 марта 2010

Для меня это звучит как паттерн Strategy .

Может быть что-то вроде этого (код в VB):

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

Примечание: GetFilteredDescription является функцией-членом вашего класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...