策略模式表明瞭解決一類算法的通用解決方案,你能夠在運行時選擇使用哪一種方案。好比如何使用不一樣的條件(好比蘋果的重量,或者顏色 )來篩選庫存中的蘋果。你能夠將這一模式應用到更普遍的領域 ,好比使用不一樣的標準 來驗證輸入的有效性,使用不一樣的方式來分析或者格式化輸入。java
策略 式包含三部份內容算法
以下圖所示:設計模式
咱們假設你但願驗證輸入的內容是否根據標準進行了恰當的格式化(好比只包含小寫字 或ide
數字)。你能夠從定義一個驗證文本(以String的形式表示)的接口入手:函數
/** * @desctiption: * @author: yinghuaYang * @date: 2019/1/8 */ public interface ValidationStrategy { boolean execute(String s); }
其次,你定義了該接口的一個或多個具體實現:this
實現1:IsAllLowerCasespa
/** * @desctiption: * @author: yinghuaYang * @date: 2019/1/8 */ public class IsAllLowerCase implements ValidationStrategy { @Override public boolean execute(String s) { return s.matches("[a-z]+"); } }
實現2:IsNumeric設計
** * @desctiption: * @author: yinghuaYang * @date: 2019/1/8 */ public class IsNumeric implements ValidationStrategy { @Override public boolean execute(String s) { return s.matches("\\d+"); } }
以後,你就能夠在你的程序中使用這些略有差別的驗證策略了:code
/** * @desctiption: * @author: yinghuaYang * @date: 2019/1/8 */ public class Validator { private final ValidationStrategy strategy; public Validator(ValidationStrategy v) { this.strategy = v; } public boolean validate(String s) { return strategy.execute(s); } public static void main(String[] args) { Validator numericValidator = new Validator(new IsNumeric()); boolean b1 = numericValidator.validate("aaaa"); System.out.println("b1: " + b1); // 返回false Validator lowerCaseValidator = new Validator(new IsAllLowerCase()); boolean b2 = lowerCaseValidator.validate("bbbb"); System.out.println("b2: " + b2); // 返回true }
到如今爲止,你應該已經意識到ValidationStrategy是一個函數接口了( 此以外,它 還與Predicate<String>具備一樣的函數描述)。這意味着咱們不須要聲明新的類來實現不一樣的策略,經過直接傳遞Lambda表達式就能達到一樣的目的,而且還更簡潔 :對象
基於java8 lambda方式改造以下:
package java8.java8example.dir策略模式; /** * @desctiption: * @author: yinghuaYang * @date: 2019/1/8 */ public class Validator { private final ValidationStrategy strategy; public Validator(ValidationStrategy v) { this.strategy = v; } public boolean validate(String s) { return strategy.execute(s); } public static void main(String[] args) { // 使用lambda表達式改造後以下 Validator numericValidator2 = new Validator((String s) -> s.matches("\\d+")); boolean b11 = numericValidator2.validate("aaaa"); System.out.println("b11: "+ b11); // 返回false ///Validator lowerCaseValidator2 = new Validator((String s) -> s.matches("[a-z]+")); /// 直接省略String也能夠 Validator lowerCaseValidator2 = new Validator((s) -> s.matches("[a-z]+")); boolean b22 = lowerCaseValidator2.validate("bbbb"); System.out.println("b22: " + b22); // 返回true } }
正如你看到的,Lambda表達式避免了採用策略設計模式時僵化的模板代碼。若是你仔細分析一下箇中原因,可能會發現,Lambda表達式實際已經對部分代碼(或策略)進行了封裝,而這就是建立策略設計模式的初衷。
所以,強烈建議對相似的問題,應該儘可能使用Lambda表達式來解決。
個人新博客鏈接: https://www.itaofly.com