什么是策略模式

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

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

策略 式包含三部分内容

  • 一个代表某个算法的接口(它是策略 式的接口)。
  • 一个或多个该接口的具体实现,它们代表了算法的多种实现(比如,实体类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. web info

    http://blog.csdn.net/qq_24473141/article/details/51363662 http://blog.sina.com.cn/s/blog_8e392fc2010 ...

  2. iOS valueForKeyPath快速计算求和、平均值、最大、最小

    iOS中开始取出数组中最大值,最小值除了使用排序的方式,还可以使用valueForKeyPath的方式直接取出 array = @[@(10),@(100),@(20),@(97)]; CGFloat ...

  3. Java并发编程(九)安全发布

    之前讨论是如何将对象封闭在线程之中,这样可以减少一些并发带来的同步和可见性问题.但是在有些时候,我们希望在多个线程间共享对象,此时必须确保安全地进行共享. [不安全发布的示例] 可见性问题:其他线程看 ...

  4. 我的第九个java程序--spring和mybatis整合(java project)

    思路:入口程序读spring的配置文件-配置文件注入给程序bean--程序拿到bean以操作对象的手法查出程序 入口程序HelloWorld.java package HelloWorld; impo ...

  5. Hibernate查询语言(HQL)

    Hibernate查询语言(HQL)与SQL(结构化查询语言)相同,但不依赖于数据库表. 我们在HQL中使用类名,而不是表名. 所以是数据库独立的查询语言. HQL的优点 HQL有很多优点. 它们如下 ...

  6. HTML5学习笔记简明版(10):废弃的元素和属性

    废弃的元素(Element) 这个小节里列出的元素在HTML5里将不再使用.现有文档升级到 HTML5的话能够使用一些替代方案. 比如parser section 能够处理isindex 元素的功能. ...

  7. linux各种路径小结

    man路径 /etc/manpath.config $MANPATH include路径 $C_INCLUDE_PATH $CPLUS_INCLUDE_PATH 动态链接库的路径 $LD_LIBRAR ...

  8. ios -将navigationbar的translucent属性设为No后,子控制器视图整体下移问题

    如果不将navigationbar.translucent = YES 会觉得颜色很浅,因为这是半透明状态 若navigationbar.translucent = NO,颜色问题解决,但是子控制器视 ...

  9. Ubuntu 下Apache安装和配置2

    在Ubuntu上安装Apache,有两种方式:1 使用开发包的打包服务,例如使用apt-get命令:2 从源码构建Apache.本文章将详细描述这两种不同的安装方式. 方法一:使用开发包的打包服务—— ...

  10. [HTML5&amp;CSS3]Transform具体解释

    Transform字面上就是变形,改变的意思. 在CSS3中transform主要包含以下几种:旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix.以下我们 ...