什么是策略模式

策略模式代表了解决一类算法的通用解决方案,你可以在运行时选择使用哪种方案。比如如何使用不同的条件(比如苹果的重量,或者颜色 )来筛选库存中的苹果。你可以将这一模式应用到更广泛的领域 ,比如使用不同的标准

来验证输入的有效性,使用不同的方式来分析或者格式化输入。

策略 式包含三部分内容

  • 一个代表某个算法的接口(它是策略 式的接口)。
  • 一个或多个该接口的具体实现,它们代表了算法的多种实现(比如,实体类Concrete- StrategyA或者ConcreteStrategyB)。
  • 一个或多个使用策略对象的客户。

如下图所示:

我们假设你希望验证输入的内容是否根据标准进行了恰当的格式化(比如只包含小写字 或

数字)。你可以从定义一个验证文本(以String的形式表示)的接口入手:

/**
* @desctiption:
* @author: yinghuaYang
* @date: 2019/1/8
*/ public interface ValidationStrategy {
boolean execute(String s);
}

其次,你定义了该接口的一个或多个具体实现:

实现1:IsAllLowerCase

/**
* @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+");
}
}

之后,你就可以在你的程序中使用这些略有差异的验证策略了:

/**
* @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具有同样的函数描述)。这意味着我们不需要声明新的类来实现不同的策略,通过直接传递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

基于 普通及Lambda方式实现策略模式的更多相关文章

  1. 【原创】从策略模式闲扯到lambda表达式

    引言 策略模式,讲这个模式的文章很多,但都缺乏一个循序渐进的过程.讲lambda表达式的文章也很多,但基本都是堆砌一堆的概念,很少带有自己的见解.博主一时兴起,想写一篇这二者的文章.需要说明的是,在看 ...

  2. [设计模式] javascript 之 策略模式

    策略模式说明 定义: 封装一系列的算法,使得他们之间可以相互替换,本模式使用算法独立于使用它的客户的变化. 说明:策略模式,是一种组织算法的模式,核心不在于算法,而在于组织一系列的算法,并且如何去使用 ...

  3. 策略模式原理及Java代码实例

    一.策略模式的定义 —— 定义了一组算法,将每个算法包装起来,并且使它们之间可以互换 —— 策略模式使这些算法在客户端调用它们的时候能够相互不影响的变化,改变不同算法的实现方式不影响客户端的使用,即策 ...

  4. Java8 in action(1) 通过行为参数化传递代码--lambda代替策略模式

    [TOC] 猪脚:以下内容参考<Java 8 in Action> 需求 果农需要筛选苹果,可能想要绿色的,也可能想要红色的,可能想要大苹果(>150g),也可能需要红的大苹果.基于 ...

  5. Java策略模式以及来自lambda的优化

    前言    设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...

  6. asp.net core 集成JWT(二)token的强制失效,基于策略模式细化api权限

    [前言] 上一篇我们介绍了什么是JWT,以及如何在asp.net core api项目中集成JWT权限认证.传送门:https://www.cnblogs.com/7tiny/p/11012035.h ...

  7. Spring 实现策略模式--自定义注解方式解耦if...else

    策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...

  8. 基于Spring实现策略模式

    背景: 看多很多策略模式,总结下来实现原理大体都差不多,在这里主要是讲解下自己基于Spring更优雅的实现方案:这个方案主要是看了一些开源rpc和Spring相关源码后的一些思路,所以在此进行总结 首 ...

  9. EffectiveJava(21)策略模式多种方式实现字符串比较

    **调用对象上的方法通常是执行该对象上的某项操作**. 如果一个对象的方法执行其他对象的操作,一个类仅仅导出这个方法(它的实例相当于一个指向该方法的指针),这样的实例被称为函数对象 例如: /** * ...

随机推荐

  1. Nginx编译安装第三方模块http_substitutions_filter_module2222

    Nginx编译安装第三方模块http_substitutions_filter_module Rming -- 阅读 安装 Http 编译 module filter nginx 模块 >> ...

  2. jsdoc — js注释

    官方文档 http://usejsdoc.org/ - sublime插件 https://github.com/spadgos/sublime-jsdocs - 生成文档 生成html: (1)安装 ...

  3. int和Integer差别

    种原始数据类型之中的一个. Java为每一个原始类型提供了封装类.Integer是java为int提供的封装类. 原始数据类型包含byte.int.char.long.float.double.boo ...

  4. java 中的valueOf方法和强转

    case1:Object 对象转String 需要强调的是String.valueOf()方法,当参数为类型是object,且值时null的时候他的处理方式 public static String ...

  5. strrev 字符串反转函数

    strrev (PHP 3, PHP 4, PHP 5) strrev -- Reverse a string Description string strrev ( string string ) ...

  6. Git使用技巧(2)-- 基本操作

    常用 Git 命令清单 作者: 阮一峰 编辑更新:shifu204 日期: 2016年9月 1日 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练 ...

  7. openfile

    linux修改open files数   概要 linux系统默认open files数目为1024, 有时应用程序会报Too many open files的错误,是因为open files 数目不 ...

  8. Eclipse 浏览(Navigate)菜单

    浏览 Eclipse 工作空间 浏览(Navigate)菜单提供了多个菜单可以让你快速定位到指定资源. 上图中 Open Type, Open Type in Hierarchy 和 Open Res ...

  9. 视频采集接口camera link 在8148中的应用

    (1)应用背景 (2)camera link 简介 (3)camera link 与8148 (4)camera link 应用实例 ---------------------author:pkf - ...

  10. 使用nginx cache缓存网站数据实践

    Nginx本身就有缓存功能,能够缓存静态对象,比如图片.CSS.JS等内容直接缓存到本地,下次访问相同对象时,直接从缓存即可,无需访问后端静态服务器以及存储存储服务器,可以替代squid功能. 1   ...