基于 普通及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