2012-01-25 127 views
0

我正在編寫一個規範,希望陳述(以明確的方式)程序員使用此模式:這種模式的名字是什麼?

我們必須對正在處理的數據應用多個過濾器。該配置允許創建這些過濾器。可以有幾個,或沒有。我不想在導出類中使用這種邏輯(因爲它可能會在未來變得很大,使用不同類型的過濾器,我們現在無法預見)。我希望它們一個接一個地運行,所以我將要求在導出類中添加一個方法:「addFilter」,它應該將對象存儲在內部數組中,然後在實際導出過程運行時讓它們執行。

我不知道問題是否足夠清楚。這就像一個鏈式戰略,但不完全是一個策略,因爲它根本不是強制性的。

同樣,問題是:我應該如何在規範中調用此模式?


編輯:什麼我試圖做一個例子:

$report = new Report(); 
$report->addFilter(new RemoveSpaces()) 
     ->addFilter(new SubstituteText($predefined_substitutions_array) 
     ->addFilter(new FixCapitals()) 
     ->addFilter(new Encode("utf8")); 
echo($report->generate()); // filters are actually used during generation. 

據稱,用戶應該能夠決定是否RemoveSpaces與否,代替什麼文本,是否利用單詞與否,使用什麼編碼等。將來肯定會在用戶(客戶端,實際)請求中添加一些過濾器。

一旦分解,過濾器應該有一個簡單的界面,該報告將稱:

foreach($this->filters as $current_filter) { 
    $data = $this->filters[$current_filter]->applyTo($data); 
} 
+0

你可以添加一個僞代碼示例來說明你在說什麼嗎? –

+0

查看編輯的問題。 –

回答

1

我實際上會說你沒有包含足夠的代碼來確定哪個模式可以用來實現你的目標,因爲你沒有顯示你的Filter類的一些示例代碼或簽名。

Report類如何與Filter類交互(反之亦然)?

我不認爲它是一個經典的責任鏈,因爲在這種情況下,每個參與者負責調用下一個參與者,通常使用自己的代碼在執行之前或之後執行。想想Windows如何將WindProc鏈接到您可以在prio WindProc之前或之後執行代碼的位置,並且可以選擇不調用它。

如果實現與核心對象相同的接口然後它們相互包裝,這些過濾器對象可能是裝飾器。但是你的代碼示例有一個簡單列表中的對象。在裝飾你會經常看到這樣的:

FilterA fA = new FilterA(coreObject); 
FilterB fB = new FilterB(fA); 
FilterC fC = new FilterC(fB); 

當然,這並不一定要通過構造這樣做,就像我說的,我們需要看到更多的代碼,知道這是一個裝飾。

我傾向於認爲你是在追求一個「管道和過濾器」模式,其中每個操作的輸出是下一個的輸入,但即使不知道更多,它也不清楚。我無法分辨每個過濾器是否作用於相同的事物(例如巨大的String),或者每個過濾器都應該與Report對象模型的某個方面相互作用。例如,如果某個報表的對象屬性爲當前的Encoder,那麼Encode("utf8")過濾器可能只是配置/安裝Encoder子類來處理磁盤持久性策略的一種方式。同時您的SubstituteText($predefined_substitutions_array)作用於報表擁有的參數集合以交換運行時值。

我會建議描述你想達到什麼,而不是如何實現它。

+0

「管道和過濾器」它是! –

1

看起來很像Chain of responsibility。請注意,每個過濾器都可以決定不在鏈上繼續。通常會有一個「鏈」對象傳遞給每個後續過濾器。

如果你不需要這些鏈式語義,它可以簡單地看作圍繞目標對象的proxies

+0

嗯...不是代理服務器,因爲我不是試圖訪問任何東西,而是將簡單的轉換和/或過濾器應用到我要導出的數據。正如我對@havexz所說的,爲了讓程序員保持簡單,我不會冒險稱之爲「責任鏈」。我想我只會描述這個模式。謝謝! –

2

我認爲你不一定必須選擇一種模式,因爲在大多數現實世界的問題中,一種模式通常不包括整個實現。因此,在您的規範中,您可以指定您的實施受到啓發的所有模式。你可以記錄你的實現與原始模式有什麼不同。

在特定情況下,它類似於Chain of Responsibility

你也可以尋找Decorator圖案,這就是還旨在實現類似功能的過濾器。

順便說一句,類似於你的另一個模式是Command Pattern。所以在你的情況下,Reportgenerate就像的Command,過濾器是列表中的命令。

+0

+1 :) 無論如何,我確定它不是Decorator模式,因爲它不會添加方法或更改我的數據對象的接口/功能。責任鏈也是我的猜測,但我不喜歡它的規範,因爲我不想誤導程序員認爲我要求的是比簡單的過濾器/數據轉換更復雜的東西。 –

+0

我的意思是說,你試圖實現的(即過濾器)也可以使用裝飾器來實現。裝飾者沒有必要添加方法,只需要有相同的接口。例如BufferedInputStream,FileInputStream等('BufferedInputStream bin = new BufferedInputStream(new FileInputStream(filename));') – havexz

+0

你是對的,但裝飾者似乎有點過於複雜的ocasion。我只需要一個轉換函數的包裝對象,並且它是否可以配置是否應用它們。 看到我編輯的問題。 我知道這是我想要的模式,而不是裝飾者。我想知道它的名字。 –