基於 普通及Lambda方式實現策略模式

什麼是策略模式

策略模式表明瞭解決一類算法的通用解決方案,你能夠在運行時選擇使用哪一種方案。好比如何使用不一樣的條件(好比蘋果的重量,或者顏色 )來篩選庫存中的蘋果。你能夠將這一模式應用到更普遍的領域 ,好比使用不一樣的標準 來驗證輸入的有效性,使用不一樣的方式來分析或者格式化輸入。java

策略 式包含三部份內容算法

  • 一個表明某個算法的接口(它是策略 式的接口)。
  • 一個或多個該接口的具體實現,它們表明了算法的多種實現(好比,實體類Concrete- StrategyA或者ConcreteStrategyB)。
  • 一個或多個使用策略對象的客戶。

以下圖所示:設計模式

咱們假設你但願驗證輸入的內容是否根據標準進行了恰當的格式化(好比只包含小寫字 或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
}

使用Lambda表達式

到如今爲止,你應該已經意識到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

相關文章
相關標籤/搜索