引言

策略模式,讲这个模式的文章很多,但都缺乏一个循序渐进的过程。讲lambda表达式的文章也很多,但基本都是堆砌一堆的概念,很少带有自己的见解。博主一时兴起,想写一篇这二者的文章。需要说明的是,在看这篇文章的时候,请忘记所有的概念。容博主一步一步的带你们入坑。

正文

假设我们有一个Hero类,其UML图如下



这个时候,我们有一个需求:

  • 我们要找出type为刺客的Hero

这时,我们先封装一个要根据type类型来筛选Hero的方法

public static List<Hero> getHero(List<Hero> heroList, String type){
List<Hero> result = new ArrayList<Hero>();
for(Hero hero : heroList){
if(type.equals(hero.getType())){
result.add(hero);
}
}
return result;
}

然后呢,做如下调用

getHero(heroList, "刺客");

突然有一天,产品突然改需求,现在的需求

  • 我们要找出stature(身高)大于170的Hero

也很简单嘛,再加一个重载的getHero方法就可以嘛,重载的getHero(List heroList, int stature)方法如下

public static List<Hero> getHero(List<Hero> heroList, int stature){
List<Hero> result = new ArrayList<Hero>();
for(Hero hero : heroList){
if(hero.getStature() > stature){
result.add(hero);
}
}
return result;
}

然后呢,做如下调用

getHero(heroList, 170);

又过了几日,产品丧心病况的又改需求,现在最新的需求

  • 要找出stature(身高)大于170并且type类型为刺客的Hero

当然,你或许说了,可以再加一个getHero(List heroList, String type, int stature)方法呀。不过呢,这种改法不够优雅。方法体中存在大量相同的代码,只是判断条件稍作改变。在这种情况下使用策略模式,就能够解决这个问题。

稍微介绍一下策略模式

策略模式

意图:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化。

主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

如何解决:将这些算法封装成一个一个的类,任意地替换。

ps:在这里,上面的算法指的就是上面提到的判断条件。我们将判断条件封装为相应的类。

此时代码结构如下图所示



那么此时的getHero方法如下所示

public static List<Hero> getHero(List<Hero> heroList, Predicate<Hero> predicate){
List<Hero> result = new ArrayList<Hero>();
for(Hero hero : heroList){
if(predicate.test(hero)){
result.add(hero);
}
}
return result;
}

然后呢,根据需求做如下调用,想找那种类型的Hero,就传那种类型的Predicate进去。

getHero(heroList,new TMPredicate());

可是呢,机智的你又发现了一个缺陷,每次新增一个算法,要新加一个实现类。于是,机智的你提出,利用匿名内部类来做调用,不写实现类,于是调用代码变成下面这样

getHero(heroList,new Predicate<Hero>() {
@Override
public boolean test(Hero t) {
return t.getStature() > 170 && "刺客".equals(t.getType());
}
});

机智的你突然间又觉得:这么写,占用了太多的行数,看起来不够美观,于是,你决定用lambda表达式来改写,于是代码最终变成下面的样子

getHero(heroList,(t)->t.getStature() > 170 && "刺客".equals(t.getType()));

好了,到这里就结束了,是不是比我们最开始的版本简洁了不少,代码优雅了很多。lambda主要的目的就是提供一个更加简洁的代码结构,但是对于初学者,它可能反而增加阅读的难度。

当然,lambda表达式除了能简化代码代码意外,还能并行处理元素,充分利用多核CPU的性能,例如下面的代码

import java.util.Arrays;
import java.util.List; public class Demo7 {
public static void main(String[] args) {
List<String> values = Arrays.asList("1","2","3","4");
print(values);
} public static void print(List<String> values){
values.parallelStream().forEach(System.out :: println);//System.out表示对象,println表示方法
}
}

输出如下

3
4
1
2

总结

本文以循序渐近的方式说明了,我们为什么要用策略模式以及如何用lambda表达式改写策略模式。希望大家有所收获。

参考文献

《JAVA8实战》

【原创】从策略模式闲扯到lambda表达式的更多相关文章

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

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

  2. [Java 8] (5) 使用Lambda表达式进行设计

    使用Lambda表达式进行设计 在前面的几篇文章中,我们已经见识到了Lambda表达式是怎样让代码变的更加紧凑和简洁的. 这一篇文章主要会介绍Lambda表达式怎样改变程序的设计.怎样让程序变的更加轻 ...

  3. C#从委托、lambda表达式到linq总结

    前言 本文总结学习C#必须知道的基础知识,委托.监视者模式.常用lambda表达式.linq查询,自定义扩展方法,他们之间有什么关系呢?匿名委托是如何演变成lambda表达式,lambda再如何导出l ...

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

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

  5. 基于 普通及Lambda方式实现策略模式

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

  6. [Java 8] (9) Lambda表达式对递归的优化(下) - 使用备忘录模式(Memoization Pattern) .

    使用备忘录模式(Memoization Pattern)提高性能 这个模式说白了,就是将需要进行大量计算的结果缓存起来,然后在下次需要的时候直接取得就好了.因此,底层只需要使用一个Map就够了. 但是 ...

  7. 用Java 8 Lambda表达式实现设计模式:命令模式

    在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...

  8. 如何优雅的将文件转换为字符串(环绕执行模式&行为参数化&函数式接口|Lambda表达式)

    首先我们讲几个概念: 环绕执行模式: 简单的讲,就是对于OI,JDBC等类似资源,在用完之后需要关闭的,资源处理时常见的一个模式是打开一个资源,做一些处理,然后关闭资源,这个设置和清理阶段类似,并且会 ...

  9. java的线程、创建线程的 3 种方式、静态代理模式、Lambda表达式简化线程

    0.介绍 线程:多个任务同时进行,看似多任务同时进行,但实际上一个时间点上我们大脑还是只在做一件事情.程序也是如此,除非多核cpu,不然一个cpu里,在一个时间点里还是只在做一件事,不过速度很快的切换 ...

随机推荐

  1. Python3 jupyter notebook 服务器搭建

    1. jupyter notebook 安装 创建 jupyter 目录 mkdir jupyter cd jupyter/ 创建独立的 Python3 运行环境,并激活进入该环境 virtualen ...

  2. c++屏蔽Win10系统快捷键

    很久之前实现的功能,也是参考其他人的实现,时间太久,具体参考哪里已经记不得了. 这里不仅能屏蔽一般的快捷键,还可以屏蔽ctrl+atl+del. ; HHOOK keyHook = NULL; HHO ...

  3. Python HTML解析模块HTMLParser(爬虫工具)

    简介 先简略介绍一下.实际上,HTMLParser是python用来解析HTML的内置模块.它可以分析出HTML里面的标签.数据等等,是一种处理HTML的简便途径.HTMLParser采用的是一种事件 ...

  4. Redis常用命令【列表】

    一.简介 基于Linked List实现,元素是字符串类型,列表头尾增删快,中间增删慢,增删元素是常态. 元素可以重复出现,最多包含2^32-1个元素. 二.命令 1.说明 1.1 B block 块 ...

  5. request获取各种路径

    equest.getRealPath() 这个方法已经不推荐使用了,代替方法是: request.getSession().getServletContext().getRealPath() 在ser ...

  6. mssql 系统函数-字符串函数专题--字符串函数大全

    mssql 系统函数 字符串函数 substring 功能简介 mssql 系统函数 字符串函数 stuff 功能简介 mssql 系统函数 字符串函数 str 功能简介 mssql 系统函数 字符串 ...

  7. 关于wordpress慢的问题

    随笔记载: 关于wordpress访问慢的原因,主要是wordpress采用了google前端库, 需替换wordpress/wp-includes/script-header.php中所有的goog ...

  8. Linux进程优先级的处理--Linux进程的管理与调度(二十二)

    1. linux优先级的表示 1.1 优先级的内核表示 linux优先级概述 在用户空间通过nice命令设置进程的静态优先级, 这在内部会调用nice系统调用, 进程的nice值在-20~+19之间. ...

  9. Linux 自动化部署Rsyslog服务

    Linux 自动化部署Rsyslog服务 源码如下: #/bin/bash #该脚本用于自动化部署Ryslog服务配置 #作者:雨中落叶 #博客:https://www.cnblogs.com/yuz ...

  10. SMB协议原理抓包分析

    SMB协议原理抓包分析 目录: 1.SMB概述 2.SMB原理 3.SMB配置 一.SMB概述 SMB(全称是Server Message Block)是一个协议名,可用于在计算机间共享文件.打印机. ...