2010-03-31 87 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