基于 普通及Lambda方式实现策略模式
什么是策略模式
策略模式代表了解决一类算法的通用解决方案,你可以在运行时选择使用哪种方案。比如如何使用不同的条件(比如苹果的重量,或者颜色 )来筛选库存中的苹果。你可以将这一模式应用到更广泛的领域 ,比如使用不同的标准
来验证输入的有效性,使用不同的方式来分析或者格式化输入。
策略 式包含三部分内容
- 一个代表某个算法的接口(它是策略 式的接口)。
- 一个或多个该接口的具体实现,它们代表了算法的多种实现(比如,实体类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方式实现策略模式的更多相关文章
- 【原创】从策略模式闲扯到lambda表达式
引言 策略模式,讲这个模式的文章很多,但都缺乏一个循序渐进的过程.讲lambda表达式的文章也很多,但基本都是堆砌一堆的概念,很少带有自己的见解.博主一时兴起,想写一篇这二者的文章.需要说明的是,在看 ...
- [设计模式] javascript 之 策略模式
策略模式说明 定义: 封装一系列的算法,使得他们之间可以相互替换,本模式使用算法独立于使用它的客户的变化. 说明:策略模式,是一种组织算法的模式,核心不在于算法,而在于组织一系列的算法,并且如何去使用 ...
- 策略模式原理及Java代码实例
一.策略模式的定义 —— 定义了一组算法,将每个算法包装起来,并且使它们之间可以互换 —— 策略模式使这些算法在客户端调用它们的时候能够相互不影响的变化,改变不同算法的实现方式不影响客户端的使用,即策 ...
- Java8 in action(1) 通过行为参数化传递代码--lambda代替策略模式
[TOC] 猪脚:以下内容参考<Java 8 in Action> 需求 果农需要筛选苹果,可能想要绿色的,也可能想要红色的,可能想要大苹果(>150g),也可能需要红的大苹果.基于 ...
- Java策略模式以及来自lambda的优化
前言 设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...
- asp.net core 集成JWT(二)token的强制失效,基于策略模式细化api权限
[前言] 上一篇我们介绍了什么是JWT,以及如何在asp.net core api项目中集成JWT权限认证.传送门:https://www.cnblogs.com/7tiny/p/11012035.h ...
- Spring 实现策略模式--自定义注解方式解耦if...else
策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...
- 基于Spring实现策略模式
背景: 看多很多策略模式,总结下来实现原理大体都差不多,在这里主要是讲解下自己基于Spring更优雅的实现方案:这个方案主要是看了一些开源rpc和Spring相关源码后的一些思路,所以在此进行总结 首 ...
- EffectiveJava(21)策略模式多种方式实现字符串比较
**调用对象上的方法通常是执行该对象上的某项操作**. 如果一个对象的方法执行其他对象的操作,一个类仅仅导出这个方法(它的实例相当于一个指向该方法的指针),这样的实例被称为函数对象 例如: /** * ...
随机推荐
- Ionic学习笔记3_ionic指令简单布局
1) 添加引用类库(ionic样式和ionic js文件) 2) 标题栏,页脚栏,内容区 3) Js引入ionic类库,添加页面操作方法和对象 4) 数据初始化 5) Html页面 ...
- RabbitMQ基础概念
转至:http://blog.csdn.net/whycold/article/details/41119807 RabbitMQ简介 AMQP,即Advanced Message Queuing P ...
- SpringBoot支持https和http
1.application.propertites #server.port=8081 server.port: 8443 server.ssl.key-store: classpath:keysto ...
- SVN各种错误提示产生原因及处理方法大全(转)
SVN各种错误提示产生原因及处理方法大全 1. svn: Server sent unexpected return value (500 Internal Server Error) in resp ...
- SQL中使用视图的优点和缺点是什么
视图的优点与缺点 在程序设计的时候必须先了解视图的优缺点,这样可以扬长避短,视图具有如下的一些优点: ● 简单性.视图不仅可以简化用户对数据的理解,也可以简化他们的操作.那些被经常使用的查询可以被定义 ...
- Windows Azure 系列-- Azure Redis Cache的配置和使用
假设还没有配置Azure Power shell 能够參照这里进行配置:http://blog.csdn.net/lan_liang/article/details/46850221 打开Azure ...
- centos6 找不到 phpize
安装php-devel yum install php-devel.i686
- with root cause 解决办法
现象:1.工程在启动的时候无异常,当页面加载到包含spring:message标签的页面时,在后台报空指针异常,同时控制 台会显示with root cause提示: 2. ...
- 006android初级篇之jni数据类型映射
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 使用JNI的副作用 一旦使用JNI,JAVA程序就丧失了JAV ...
- poj 2195(KM求最小权匹配)
题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...