什么是策略模式

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

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

策略 式包含三部分内容

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

如下图所示:

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

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

  1. /**
  2. * @desctiption:
  3. * @author: yinghuaYang
  4. * @date: 2019/1/8
  5. */
  6. public interface ValidationStrategy {
  7. boolean execute(String s);
  8. }

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

实现1:IsAllLowerCase

  1. /**
  2. * @desctiption:
  3. * @author: yinghuaYang
  4. * @date: 2019/1/8
  5. */
  6. public class IsAllLowerCase implements ValidationStrategy {
  7. @Override
  8. public boolean execute(String s) {
  9. return s.matches("[a-z]+");
  10. }
  11. }

实现2:IsNumeric

  1. **
  2. * @desctiption:
  3. * @author: yinghuaYang
  4. * @date: 2019/1/8
  5. */
  6. public class IsNumeric implements ValidationStrategy {
  7. @Override
  8. public boolean execute(String s) {
  9. return s.matches("\\d+");
  10. }
  11. }

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

  1. /**
  2. * @desctiption:
  3. * @author: yinghuaYang
  4. * @date: 2019/1/8
  5. */
  6. public class Validator {
  7. private final ValidationStrategy strategy;
  8. public Validator(ValidationStrategy v) {
  9. this.strategy = v;
  10. }
  11. public boolean validate(String s) {
  12. return strategy.execute(s);
  13. }
  14. public static void main(String[] args) {
  15. Validator numericValidator = new Validator(new IsNumeric());
  16. boolean b1 = numericValidator.validate("aaaa");
  17. System.out.println("b1: " + b1); // 返回false
  18. Validator lowerCaseValidator = new Validator(new IsAllLowerCase());
  19. boolean b2 = lowerCaseValidator.validate("bbbb");
  20. System.out.println("b2: " + b2); // 返回true
  21. }

使用Lambda表达式

到现在为止,你应该已经意识到ValidationStrategy是一个函数接口了( 此之外,它 还与Predicate具有同样的函数描述)。这意味着我们不需要声明新的类来实现不同的策略,通过直接传递Lambda表达式就能达到同样的目的,并且还更简洁 :

基于java8 lambda方式改造如下:

  1. package java8.java8example.dir策略模式;
  2. /**
  3. * @desctiption:
  4. * @author: yinghuaYang
  5. * @date: 2019/1/8
  6. */
  7. public class Validator {
  8. private final ValidationStrategy strategy;
  9. public Validator(ValidationStrategy v) {
  10. this.strategy = v;
  11. }
  12. public boolean validate(String s) {
  13. return strategy.execute(s);
  14. }
  15. public static void main(String[] args) {
  16. // 使用lambda表达式改造后如下
  17. Validator numericValidator2 = new Validator((String s) -> s.matches("\\d+"));
  18. boolean b11 = numericValidator2.validate("aaaa");
  19. System.out.println("b11: "+ b11); // 返回false
  20. ///Validator lowerCaseValidator2 = new Validator((String s) -> s.matches("[a-z]+"));
  21. /// 直接省略String也可以
  22. Validator lowerCaseValidator2 = new Validator((s) -> s.matches("[a-z]+"));
  23. boolean b22 = lowerCaseValidator2.validate("bbbb");
  24. System.out.println("b22: " + b22); // 返回true
  25. }
  26. }

正如你看到的,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. Vue 组件4 动态组件

    动态组件 通过使用保留的<component>元素,动态的绑定到它的is特性,我们让多个组件同时使用同一个挂载点,并动态切换: var vm = new Vue({ el: '#examp ...

  2. Ubuntu vsftp复制文件到远端时错误,Permission denied

    Ubuntu 下复制文件到远端时错误,Permission denied 失败原因如下: (1)vsftp默认配置不允许上传文件 解决办法:修改配置文件 vi /etc/vsftpd.conf. 将& ...

  3. Consul实现原理系列文章1: 用Raft来实现分布式一致性

    工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.在前一篇文章中,我介绍了Raft算法.这篇文章会讲讲Consul是如何使用Raft算法来实现分布式一 ...

  4. 把world转成html

    本来用php转的 效果不太理想 很不稳定 最后试了下java 效果不错 只记录java的方法好了 其实他们的原理都是一样的啊,都是用到了微软的com 首先是准备工作 下载(明确dll的版本是64位的还 ...

  5. Web应用程序使用Hibernate

    在本文中,我们将学习使用hibernate创建一个Web应用程序. 对于创建Web应用程序,我们使用JSP表示逻辑层,使用Bean类表示数据,以及使用DAO类操作数据库.在hibernate中创建简单 ...

  6. Openstack(Kilo)安装系列之环境准备(二)

    控制节点.网络节点.计算节点: 一.配置源 1.配置EPEL源 yum install http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-rel ...

  7. WPF简介:VS创建桌面应用程序

    1.简介 1/ 什么是WPF WPF,Windows Presentation Foundation也,译过来就是"Windows呈现基础",你看它的目的非常明确,就是用来把数据& ...

  8. SQL.Cookbook 读书笔记2 查询结果排序

    第二章 查询结果排序 2.1 按查询字段排序 order by sal asc; desc;-- 3表示sal 2.2 按子串查询 );--按job的最后两个字符排序 2.3 对字符数字混合排序 cr ...

  9. 阿里云里Centos 7 PHP7环境配置 LNMP

    首先更新系统软件</str> $ yum update 安装nginx</str></str> 1.安装nginx源 $ yum localinstall http ...

  10. PHP 规划(收藏的一些好博文)

    2014-10-15 01:30 36870人阅读 评论(34) 收藏 举报 分类: PHP/DHTML/Other(237) 版权声明:本文为博主原创文章,未经博主允许不得转载. PHP程序员的技术 ...