[译]lambda表达式对 SAM (单个抽象方法类)type的处理方式
在阅读Venkat Subramaniam的著作《Functional Programming in Java》 之后,方法模式和lambda完美结合让我印象深刻。
这种模式经常用作数据源处理,但也适用于类似的情况。这种模式可以让你集中注意力在核心功能点上,而不用担心类里面有过多重复的代码。
这里创建了一个事务处理作为事例。
接口 Transaction,他有一个执行方法。
import java.sql.Connection;
import java.sql.SQLException; public interface Transaction{
public void execute(Connection connection) throws SQLException;
}
这个接口代表我们想在事务中执行什么操作。这是一个 SAM(Single Abstract Method) 类型,意味着我们能够使用lambda表达式去实现他。
然后我们轮到我们的主角登场,TransactionHandler。
import java.sql.Connection;
import java.sql.DriverManager; public class TransactionHandler { public static void runInTransaction(Transaction transaction) throws Exception { Connection dbConnection = createDatabaseConnection();
dbConnection.setAutoCommit(false); try { System.out.println("Starting transaction");
transaction.execute(dbConnection); System.out.println("Committing transaction");
dbConnection.commit(); } catch (Exception e) { System.out.println(e.getMessage());
System.out.println("Rolling back...");
dbConnection.rollback();
} finally {
dbConnection.close();
}
} private static Connection createDatabaseConnection() throws Exception { Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://localhost:3306/ticket_system", "user", "password");
}
}
他包含了一个静态方法,他的职责是运行我们的事务和在异常情况下回滚.
我创建了一个简单的票务系统去展示TransactionHandler是怎么样和lambda一起工作的.
首先是一个成功的事务:
@Test
public void testSuccessfulPurchase() throws Exception { TransactionHandler.runInTransaction(connection -> { int ticketId = findAvailableTicket(connection); reserveTicket(ticketId, connection);
markAsBought(ticketId, connection);
}); assertEquals(getNrOfTicketsIn(TicketState.AVAILABLE), 9);
assertEquals(getNrOfTicketsIn(TicketState.RESERVED), 0);
assertEquals(getNrOfTicketsIn(TicketState.BOUGHT), 1);
}
控制台输出:
Starting transaction
Reserving ticket with id 1
Marking ticket with id 1 as bought
Committing transaction
然后是失败的事务:
@Test
public void testFailedPurchase() throws Exception { TransactionHandler.runInTransaction(connection -> { int ticketId = findAvailableTicket(connection); reserveTicket(ticketId, connection);
throw new IllegalStateException("Not approved credit card");
}); assertEquals(getNrOfTicketsIn(TicketState.AVAILABLE), 10);
assertEquals(getNrOfTicketsIn(TicketState.RESERVED), 0);
assertEquals(getNrOfTicketsIn(TicketState.BOUGHT), 0);
}
这个测试预定了一张票,然后抛出异常,触发回滚取消预约;
控制台输出:
Starting transaction
Reserving ticket with id 1
Not approved credit card
Rolling back...
lambda表达式的处理方式是简洁优雅的,而匿名内部类需要创建类并实例化他,你不觉得他有些太罗嗦了吗?
留意我们是如何使用lambda表达式作为一个工具去测试TransactionHandler的每个方面
你能在这里找到完整的例子 GitHub
*英文链接:deadCodeRising
*原创译文
[译]lambda表达式对 SAM (单个抽象方法类)type的处理方式的更多相关文章
- Java 终于有 Lambda 表达式啦~Java 8 语言变化——Lambda 表达式和接口类更改【转载】
原文地址 en cn 下载 Demo Java™ 8 包含一些重要的新的语言功能,为您提供了构建程序的更简单方式.Lambda 表达式 为内联代码块定义一种新语法,其灵活性与匿名内部类一样,但样板文件 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_03 过滤器_2_FileNameFilter过滤器的使用和Lambda表达式
复制一份上一节的代码 匿名内部类的形式 FilenameFilter 只有一个Accept方法.这样我们就可以使用lambda表达式 lambda表达式的前提条件 参数类型和,返回的大括号 都可以省掉 ...
- jdk8 lambda表达式总结
Java8 lambda表达式10个示例 1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnab ...
- 接口和lambda表达式笔记
接口 接口是双方,即服务提供方和想让它们的对象对服务是可用的那些类,之间约定的一种机制. 声明一个接口 public interface IntSequence{ //不提供实现,则该方法为抽象方法, ...
- 07_Java8新增的Lambda表达式
[Lambda表达式概述] Lambda表达式支持将代码块作为方法参数,Lambda表达式允许将使用简洁的代码来创建只有一个抽象方法的接口的实例.(这种接口称为函数式接口) [入门实例] packag ...
- C++11中新特性之:lambda 表达式
首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-i ...
- Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等
一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接 ...
- Java 8 Lambda表达式,让你的代码更简洁
Lambda表达式是Java 8一个非常重要的新特性.它像方法一样,利用很简单的语法来定义参数列表和方法体.目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift等都已经支持La ...
- Java 常用的几个lambda表达式
Lambda表达式是Java 8一个非常重要的新特性.它像方法一样,利用很简单的语法来定义参数列表和方法体.目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift,C#等都已经支 ...
随机推荐
- hadoop节点之间通信问题
前天遇到一个hadoop问题,由于之前都是伪分布的情况,没有真正的涉及到集群的环境,最近按照一些资料自己搭建了一个集群环境,三台虚拟机,一个master,两个slave,利用jps查看节点信息,启动了 ...
- ArcGIS Server中创建的两个账户有什么区别
新手常常有这样的疑问: 在安装ArcGIS Server的时候创建的账户和在ArcGIS Server Manager上面创建的账户有什么区别? 解答:前者是是为ArcGIS Server创建的操作系 ...
- vue2.0实现页面刷新时某个input获得focus
通过自定义指令:
- 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分
题目描述 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好, ...
- HTML5<canvas>标签:使用canvas元素在网页上绘制渐变和图像(2)
详细解释HTML5 Canvas中渐进填充的参数设置与使用,Canvas中透明度的设置与使用,结合渐进填充与透明度支持,实现图像的Mask效果. 一:渐进填充(Gradient Fill) Canva ...
- 关于JS中array对象的push( )
push()的参数传的是指针,不是值. var arr = new Array(); var item = 5; arr.push(item); var item = 6; 运行以上代码,arr中的元 ...
- fail2ban软件 +ssh密钥登录
fail2ban可以监视你的系统日志,然后匹配日志的错误信息(正则式匹配)执行相应的屏蔽动作(一般情况下是调用防火墙屏蔽),如:当有人在试探你的SSH.SMTP.FTP密码,只要达到你预设的次数,fa ...
- POJ2559 Largest Rectangle in a Histogram (单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26012 ...
- 买卖股票的最佳时机 [ leetcode ]
原题地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/ 给定一个数组,它的第 i 个 ...
- 小程序根据input输入,动态设置按钮的样式
[需求]实现当手机号已填写和协议已勾选时,“立即登录”按钮变亮,按钮可点击:若有一个不满足,按钮置灰,不可点击:实现获取短信验证码,倒计时提示操作:对不满足要求内容进行toast弹窗提示. <v ...