用函式正規化實現戰略模式
戰略模式又稱為策略模式,其目的是讓我們能使用不同但可互換的演算法。現在我們在另一個實際例子中使用這種模式。我們想要概括一個流程,該流程在輸入中獲取文字,使用給定的條件對其進行過濾,並在最終格式化或轉換後將其列印在標準輸出上。換句話說,我們需要概括2個行為:一個過濾文字,另一個轉換它。第一步是將這兩種行為的抽象定義放入一個介面中。
interface TextFormatter { boolean filter(String text); String format(String text); } |
在此之後,可以開發一個實現一般流程的類來釋出一個文字,該文字與TextFormatter介面(策略)的例項一起傳遞,該例項又封裝了使用者想要如何過濾和格式化文字的細節。
public class TextEditor { private final TextFormatter textFormatter; public TextEditor(TextFormatter textFormatter) { this.textFormatter = textFormatter; } public void publishText(String text) { if (textFormatter.filter( text )) { System.out.println( textFormatter.format( text ) ); } } } |
我們現在可以提供策略的多個實現。最明顯的一個接受任何文字並按原樣列印。
public class PlainTextFormatter implements TextFormatter { @Override public boolean filter( String text ) { return true; } @Override public String format( String text ) { return text; } } |
另一個可以用於逐行解析日誌檔案以搜尋錯誤訊息,因此它只接受以“ERROR”開頭的句子並以大寫形式列印它們。
public class ErrorTextFormatter implements TextFormatter { @Override public boolean filter( String text ) { return text.startsWith( "ERROR" ); } @Override public String format( String text ) { return text.toUpperCase(); } } |
最後,我們可以更具想象力,以小寫字母列印僅短於20個字元的文字。
public class ShortTextFormatter implements TextFormatter { @Override public boolean filter( String text ) { return text.length() < 20; } @Override public String format( String text ) { return text.toLowerCase(); } } |
此時,我們可以建立一個TextEditor,傳遞一個TextFormatter例項,該例項特定於我們想要執行的文字釋出型別。
TextEditor textEditor = new TextEditor( new ErrorTextFormatter() ); textEditor.publishText( "ERROR - something bad happened" ); textEditor.publishText( "DEBUG - I'm here" ); |
到目前為止一直很好,但再一次感覺這種實現比它更加冗長。這一次,唯一相關的訊號是TextEditor類的publishText中實現的邏輯。TextFormatter介面定義的2個行為可以使用2個函式傳遞給publishText方法:一個謂詞來過濾要釋出的測試;另外一個是UnaryOperator(一個函式轉換另一個相同型別的物件)來格式化之前將其傳送到標準輸出。
public static void publishText( String text, Predicate<String> filter, UnaryOperator<String> format) { if (filter.test( text )) { System.out.println( format.apply( text ) ); } } |
透過這種方式,我們可以按原樣釋出任何文字,如下所示由PlainTextFormatter完成:
publishText( "DEBUG - I'm here", s -> true, s -> s ); |
或者可以重新實現ErrorTextFormatter提供的功能,傳遞一個僅接受以“ERROR”開頭的文字的Predicate和一個將String轉換為大寫的函式。
publishText( "ERROR - something bad happened", s -> s.startsWith( "ERROR" ), String::toUpperCase ); |
對這種更緊湊的解決方案的一個常見反對意見是,在類中顯式實現TextFormatter允許擁有一個可以重用的策略庫,而不是為每個單獨的呼叫重複它們的實現。然而,沒有什麼能阻止我們對函式採用類似的方法並將它們收集在這樣一個合適的庫中。
public class TextUtil { public boolean acceptAll(String text) { return true; } public String noFormatting(String text) { return text; } public boolean acceptErrors(String text) { return text.startsWith( "ERROR" ); } public String formatError(String text) { return text.toUpperCase(); } } |
透過這種方式,我們可以重用定義的函式,而不是使用匿名lambdas:
publishText( "DEBUG - I'm here", TextUtil::acceptAll, TextUtil::noFormatting ); publishText( "ERROR - something bad happened", TextUtil::acceptErrors, TextUtil::formatError ); |
值得注意的是,這些函式實際上比策略類更精細(它們可以以任何類不可用的方式組合),並允許更好的可重用性。
相關文章
- 實戰JS正規表示式JS
- 正規表示式完整教程(略長)
- JS實現正規表示式JS
- 正規表示式詳解及實戰
- 正規表示式-基礎實戰篇
- Oracle正規表示式函式Oracle函式
- 用Map+函式式介面來實現策略模式函式模式
- JS正規表示式完整教程(略長)JS
- 20個實用正規表示式
- 使用函式式實現觀察者模式模式函式模式
- 函式依賴與資料庫正規化函式資料庫
- SqlServer—大話函式依賴與正規化SQLServer函式
- 正規表示式☞相關函式函式
- 正規表示式的應用實現郵箱輸入
- 邏輯函式的規範正規化:SOP與POS form函式ORM
- 正規表示式之python實現Python
- EditPlus中的正規表示式 實戰(1)
- EditPlus中的正規表示式實戰(5)
- EditPlus中的正規表示式實戰(6)
- 正規表示式支配匹配模式模式
- 正規表示式 貪婪模式模式
- 模式匹配與正規表示式模式
- 金地商置延續金地集團深耕戰略,實現產業戰略規模升級產業
- 用函式實現模組化程式設計一函式程式設計
- 用函式實現模組化程式設計二函式程式設計
- 用函式實現模組化程式設計三函式程式設計
- YK戰略能否實現
- 資料庫系統------函式依賴與正規化資料庫函式
- 10個實用的PHP正規表示式PHP
- 15個實用的PHP正規表示式PHP
- 15 個實用的 PHP 正規表示式PHP
- 戰略實施的模式(轉載)模式
- 正規表示式模式修飾符模式
- 常用正規表示式匹配模式(java)模式Java
- 函式正規化入門(惰性求值與函式式狀態)函式
- 正規表示式match()函式和exec()函式的區別函式
- php之正規表示式函式總結PHP函式
- ObjectC Hook函式的實現與實戰ObjectHook函式