基于 普通及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)策略模式多种方式实现字符串比较
**调用对象上的方法通常是执行该对象上的某项操作**. 如果一个对象的方法执行其他对象的操作,一个类仅仅导出这个方法(它的实例相当于一个指向该方法的指针),这样的实例被称为函数对象 例如: /** * ...
随机推荐
- mysql官网下载页面
http://dev.mysql.com/downloads/mysql/5.6.html#downloads
- nginx 模块简介
nginx模块一般分为5类:核心模块.标准http模块.可选http模块.邮件服务模块.第三方模块. 其中核心模块和标准http模块在快速编译之后就包含在了nginx中. 主要看一下核心模块.标准ht ...
- 李洪强iOS开发之OC[004] - OC和C的差异的学习
- 从‘void*’到‘int’的转换损失精度
在CentOS6.2 64位下编译一下代码,不通过,提示 ./11_2.cpp: In function ‘int main(int, char**)’:./11_2.cpp:28: 错误:从‘voi ...
- linux虚拟文件系统vfs
linux可以挂载不同的文件系统(EXT2,FAT,NTFS),用同一的样式呈现给用户,读写操作用起来都一样,这是怎样做到的呢? linux内核在各种不同的文件系统格式上做了一个抽象层,使得文件.目录 ...
- PHP基础之Autoload
PHP的自动加载autoload机制很重要,这里做2个小练习 原创文章,转载请注明:http://www.cnblogs.com/phpgcs 文件结构如下,2种方式实现自动加载 1,自定义函数 2, ...
- Spring Boot MongoDB JPA 简化开发
使用SpringBoot提供的@Repository接口,可以完成曾经需要大量代码编写和配置文件定制工作.这些以前让新手程序员头疼,让有经验的程序员引以为傲的配置,由于框架的不断完善,变得不那么重要, ...
- Servlet Session 跟踪
HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录. 但是仍然有以下三种方式来维持 ...
- Codeforces Round #398 (Div. 2) BCD
B:The Queue 题目大意:你要去办签证,那里上班时间是[s,t), 你知道那一天有n个人会来办签证,他们分别是在时间点ai来的.每个人办业务要花相同的时间x,问你什么时候来 排队等待的时间最少 ...
- java FTP 上传下载删除文件
在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件 ...