singleton pattern

singleton-pattern-img

 

Filter Pattern用途

Filter Pattern,常用於過濾某像需求是否符合規則(規則可以是一連串的檢查),若符合檢察會做出相對應的事情。

 

基本所需的結構有Manager、Target、Chain、Filter四個。

Manager:主要用來設定Chain和Target兩個類別使用新增Filter和檢查也都是用Manager來控制。

Target:用來控制對應的輸出,在下面的實作中輸出直接和Filter的回傳相同所以在範例中可能比較看不出來功用。

Chain:主要功能在處裡Filter。

Filter:主要用於處裡來源資料是否符合的判斷。

Filter Patt設計概念

1. Target設計:Target執行的輸出是輸入經過Chain後產生的結果,成為Target的輸入,在經由Target的處裡以後,可以得到Target的輸出結果,也就是說,可以依照不同的介面套換不同的Target來變化同樣的Chain後產生的結果但是回覆給使用者的訊息不同,舉例來說Chain回傳結果為bool,TargetA可以設定true回應A,false則回應B,那若有另外一個使用者需要true的時候回應C,false的時候則回應D的時候,可以製作一個新的Target滿足使用者需求。

2. Chain設計:Chain單純很多就是對於輸入的資訊傳給每個Filter過濾,並且回傳結果。在底下的實例中有對Chain做些許的修正,並不影響主要架構。

3. Filter設計:Filter主要是收到輸入後過濾該項輸入產生正確的輸出,相對單純許多,實作時只需考慮該項單一的檢查就可以了。

實際範例

public interface MsgFilter_IF

{

string execute(string request);

}

說明:MsgFilter_IF是Filter類別的介面,在這邊filter比較單純就是execute還有他所輸入的引數為字串,且輸出結果也是字串。

public class MsgFilterChain

{

private List<MsgFilter_IF> filters = new List<MsgFilter_IF>();

private MsgTarget target;

 

public void addFilter(MsgFilter_IF filter)

{

filters.Add(filter);

}

 

public string execute(string str)

{

if (string.IsNullOrEmpty(str)) return target.execute(“”);

string tmp = “”;

foreach (MsgFilter_IF filter in filters)

{

tmp = filter.execute(str);

if (tmp != “”) return target.execute(tmp);

}

return target.execute(tmp);

}

 

public void setTarget(MsgTarget target)

{

this.target = target;

}

}

說明:MsgFilterChain比較不同的地方是execute內若是輸入空的字串或是根本沒有給引述值的狀況直接回傳空字串(空字串代表輸入字串中沒有符合Filter規則的字串),其他的函數就是大概固定不變的格式。

public class MsgFilterManager

{

MsgFilterChain filterChain;

 

public MsgFilterManager(MsgTarget target)

{

filterChain = new MsgFilterChain();

filterChain.setTarget(target);

}

 

public void setFilter(MsgFilter_IF filter)

{

filterChain.addFilter(filter);

}

 

public string filterStr(string str)

{

return filterChain.execute(str);

}

}

說明:Filter範例我這邊只做一個,若要檢查多個只要製造其他的Filter然後在MsgFilterManager內加入Filter(使用setFilter()函數)就可以了,另外檢查字串使用filterStr()函數,就會回傳相對應的結果字串了,另外特別要注意的是,MsgFilterManager的建構式建構的時候就必須要產生MsgTarget的值了,是需要注意的地方。

public class IllegalStrCheckFilter : MsgFilter_IF

{

private string[] checklist;

private string JsonPath = AppDomain.CurrentDomain.BaseDirectory + @”Xml\SUCheckList.json”;

 

public string execute(string str)

{

foreach (string i in checklist)

{

if (str.IndexOf(i) != -1) return “內文有不合法文字”;

}

return “”;

}

//JsonString=[“NAS”,”About iTe2″,”關於詮力”,”網路儲存伺服器”]

public IllegalStrCheckFilter()

{

string strtmp = System.IO.File.ReadAllText(JsonPath);

checklist = JsonConvert.DeserializeObject<string[]>(strtmp);

}

}

說明:這個Filter主要做的事情就是,將外部的Json檔案讀進程式,Json檔案內容是Array的格式,輸入的字串會被拿來檢查字串內是否有符合Array內的字串,實作方面每個Filter都需要使用剛剛定義好了MsgFilter_IF介面,接下來我這邊在建構IllegalStrCheckFilter的時候將Json檔案的資料讀出來轉成list的型態,提供給execute檢查的時候能夠使用,execute方面裡面就是很簡單的用迴圈檢查是否有相對應的字串出現。

 

public static void Main(string[] args)

{

MsgFilterManager filterManager = new MsgFilterManager(new MsgTarget());

filterManager.setFilter(new IllegalStrCheckFilter());

string teststr = “詮力科技為一專業的軟體開發服務公司,十一年來以前瞻的商業眼光搭配完善的專業技術與全力的服務使命,致力於提供金融產業、政府公部門以及中小企業完善的「行動商務簡訊應用整合服務」、「MMS」、「簡訊廣播站」、「信用卡安全防偽系統」、「雲端儲存設備」、「Share Point解決方案」以及「SSO單一登入系統建置」。詮力更深信客戶的需求和服務應永遠優先於產品的制式規劃與銷售,為客戶提供客製化的產品規劃,先進科技的價值才能充份地被瞭解。”

string msg = filterManager.filterStr(teststr);

}

說明:以上為Filter Pattern的測試先用MsgFilterManager類別產生一個對應輸出為MsgTarget類別的物件filterManager再將IllegalStrCheckFilter類別的Filter加入filterManager物件中,接下來我們製造一個要檢查的字串,然後將字串拿去檢查,以上的範例因為字串內沒有先前設定的篩選字串,所以msg字串會得到空字串,我們可以拿此結果當作判斷條件判斷檢查的字串內是否有被filter篩選出來。

結語: 這次的Filter Pattern其實使用的平率很高,因為當系統需要一連串檢查的時候就可以使用這樣的方式來解決問題,當然不使用這麼複雜的方式也是可以解決一連串處理的問題,但是用這樣的方式撰寫程式可以讓程式較好擴充,也可以大量重複的使用,目前我大多數拿這個Pattern使用的狀況都是用來做多項的字串檢查,像是當需求需要對使用者輸入的字串做一連串的檢查的時候我會使用這個pattern來解決問題。


發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料