用了 Lambda 之后,发现可以忘记设计模式了
设计模式是过去的一些好的经验和套路的总结,但是好的语言特性可以让开发者不去考虑这些设计模式。面向对象常见的设计模式有策略模式、模板方法、观察者模式、责任链模式以及工厂模式,使用Lambda表达式(函数式编程思维)有助于避免面向对象开发中的那些固定代码。下面挑选了策略模式和职责链模式两个案例进行分析。
案例1:策略模式
当我们解决一个问题有不同的解法的时候,又不希望客户感知到这些解法的细节,这种情况下适合使用策略模式。策略模式包括三个部分:
- 解决问题的算法(上图中的Strategy);
- 一个或多个该类算法的具体实现(上图中的ConcreteStrategyA、ConcreteStrategyB和ConcreteStrategyC)
- 一个或多个客户使用场景(上图中的ClientContext)
面向对象思路
首先定义策略接口,表示字符串的处理算法:
然后定义具体的实现类,即不同的验证算法:
最后定义客户使用场景,代码如下图所示。Validator是为客户提供服务时使用的上下文环境,每个Valiator对象中都封装了具体的Strategy对象,在实际工作中,我们可以通过更换具体的Strategy对象来进行客户服务的升级,而且不需要让客户进行升级。
函数式编程思路
如果使用Lambda表达式考虑,你会发现ValidationStrategy就是一个函数接口(还与Predicate具有同样的函数描述),那么就不需要定义上面那些实现类了,可以直接用下面的代码替换,原因是Lambda表达式内部已经对这些类进行了一定的封装。
案例2:责任链模式
在某些场景下,需要对一个对象做一系列的工作,这些工作分别是由不同的类完成的,这时候就比较适合使用责任链模式。责任链模式的主要组成部分包括三个:
- 管理操作序列的抽象类,在该抽象类里有会有一个对象记录当前对象的后继操作对象;
- 一些具体的操作对象,这些操作对象会以一个链表的形式组织起来
- 一个使用该模式的客户端组件,该组件只需要跟一个组件打交道就好,不需要跟很多个操作对象耦合在一起。
面向对象思路
首先看下我们这里定义了一个抽象类ProcessingObject,其中successor字段用于管理该对象的后继操作对象;handle接口作为对外提供服务的接口;handleWork作为实际处理对象的操作方法。
接下来可以定义两个具体的操作对象,如下面代码所示。PS:这里《Java 8实战》书中用的是replaceAll方法是不太合适的,这个点可以参考我们之前的文章——020:举几个String的API以及案例 )。
最后,你就可以在Client中将这上面两个具体的操作类对象构成一个操作序列,参见下面的代码:
函数式编程思路
如果使用函数式编程思维,那么职责链模式就直接了——y=f(x)和z=g(x)这两个方法都是要对x做处理,那么如果将这两个函数组合在一起,就会形成r=f(g(x))的情况,也就是可以使用Lambda表达式中的addThen来串联起多个处理过程。
上面是利用Java原生的Lambda表达式实现的职责链模式,我们也可以使用前面一篇文章——vavr:让你像写Scala一样写Java)中介绍过的vavr库来实现,代码如下所示:
总结
可以看出,函数式编程思维跟面向对象编程思维的思考方式是不同的,表达力更强,因此,作为开发者是时候认真学习下函数式编程思维了,作为Java开发者,我准备先从Lambda表达式开始学起。
用了 Lambda 之后,发现可以忘记设计模式了的更多相关文章
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- Java 8新特性(Lambda,Stream API)
由于最近总监要求学习Java 8的一些知识,就去网上找了 一套教程来学习学习,将学习结果做一个小的总结记录,方便以后使用: 1.Java 8的优点 2.Lambda表达式优点 2.1Lambda实例 ...
- <代码整洁之道>、<java与模式>、<head first设计模式>读书笔记集合
一.前言 几个月前的看书笔记 ...
- C#设计模式(15)——命令模式(Command Pattern)
一.前言 之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的 ...
- 忘记commit的一次教训
由于业务需求,已经上线的系统新增加了一些需求,其中一个需求是,从一个SQLSERVER数据库导入数据到生产的ORCLE数据库, 由于我的失误导致系统上线后 生产的Oracle数据没有导入成功,但是在本 ...
- ubuntu忘记登录账户以及密码
笔者在诸多方面仍然是初学者.感兴趣的方面也很多,电脑装上ubuntu14.04也有一段时间了,但仍然在不断学习更多基础的东西. 因为对于命令行界面还有些不习惯,所以一直依赖于图形界面,需要使用终端的时 ...
- 设计模式 之 Organizing the Catalog 组织目录
Design patterns vary in their granularity and level of abstraction. Because thereare many design pat ...
- java设计模式--基础思想总结--父类引用操作对象
看设计模式的相关书籍也有一段时间了,一开始其实是抱着作为java三大框架的基础知识储备来学习的,不过到后来,才发现,在设计模式的一些准则装饰下,java的面向对象威力才真正地体现出来,后面的将会陆续地 ...
- JAVA设计模式总结之23种设计模式
上一篇总结了设计模式的六大原则<JAVA设计模式总结之六大设计原则>,这一篇,正式进入到介绍23种设计模式的归纳总结. 一.什么是设计模式 ...
随机推荐
- Caffe源码-SyncedMemory类
SyncedMemory类简介 最近在阅读caffe源码,代码来自BVLC/caffe,基本是参照网络上比较推荐的 Blob-->Layer-->Net-->Solver 的顺序来分 ...
- Another git process seems to be running in this repository
今天在推送项目的时候git突然报如题的错误.查了一下是由于git被另外一个程序占用,产生原 原因在于Git在使用过程中遭遇了崩溃,部分被上锁资源没有被释放. 解决方案也很简单,在git中找到对应的in ...
- tp5.1批量删除商品
选中要删除的商品,点击批量删除 先在控制器使用sql语句查出商品信息goods 然后在html源码中使用goods变量. <table> {foreach $goods as $item} ...
- Springboot vue.js html 跨域 前后分离 shiro权限 集成代码生成器
本代码为 Springboot vue.js 前后分离 + 跨域 版本 (权限控制到菜单和按钮) 后台框架:springboot2.1.2+ mybaits+maven+接口 前端页面:html + ...
- Android 状态栏通知 Notification
private NotificationManager manager; private Notification.Builder builder; @Override protected void ...
- 拖动条(SeekBar)的功能与用法
拖动条和进度条非常相似,只是进度条采用颜色填充来表明进度完成的程度,而拖动条则通过滑块的位置来标识数值——而且拖动条允许用户拖动滑块来改变值,因此拖动条通常用于对系统的某种数值进行调节,比如调节音量等 ...
- Android 线性布局 计算器
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- ORACLE各种对象、概念及关系整理(一文读懂)
下面是我整理(抄袭)的一些Oracle数据库相关概念对象的理解,如有疏漏,欢迎指正.至于整理这篇文章的目的:主要是网上的内容太散了,这样整理一遍可以加深理解,也便于后续查阅.就我的理解:下述内容应该可 ...
- Mongdb可视化工具Studio 3T的使用
一.官网地址 https://studio3t.com/ 二.下载和安装 点击DOWNLOAD即可下载 按照自己电脑系统进行选择,然后填写邮箱和选择行业,第一次登录如果不提交不会下载,下载完成是一个z ...
- 非常详细的 (VMware安装Centos7超详细过程)
本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.软硬件准备 软件:推荐使用VMwear,我用的是VMwear 12 镜像:Ce ...