在阅读Venkat Subramaniam的著作《Functional Programming in Java》 之后,方法模式和lambda完美结合让我印象深刻。

这种模式经常用作数据源处理,但也适用于类似的情况。这种模式可以让你集中注意力在核心功能点上,而不用担心类里面有过多重复的代码。

这里创建了一个事务处理作为事例。

接口 Transaction,他有一个执行方法。

  1. import java.sql.Connection;
  2. import java.sql.SQLException;
  3.  
  4. public interface Transaction{
  5. public void execute(Connection connection) throws SQLException;
  6. }

这个接口代表我们想在事务中执行什么操作。这是一个 SAM(Single Abstract Method) 类型,意味着我们能够使用lambda表达式去实现他。

然后我们轮到我们的主角登场,TransactionHandler。

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3.  
  4. public class TransactionHandler {
  5.  
  6. public static void runInTransaction(Transaction transaction) throws Exception {
  7.  
  8. Connection dbConnection = createDatabaseConnection();
  9. dbConnection.setAutoCommit(false);
  10.  
  11. try {
  12.  
  13. System.out.println("Starting transaction");
  14. transaction.execute(dbConnection);
  15.  
  16. System.out.println("Committing transaction");
  17. dbConnection.commit();
  18.  
  19. } catch (Exception e) {
  20.  
  21. System.out.println(e.getMessage());
  22. System.out.println("Rolling back...");
  23. dbConnection.rollback();
  24. } finally {
  25. dbConnection.close();
  26. }
  27. }
  28.  
  29. private static Connection createDatabaseConnection() throws Exception {
  30.  
  31. Class.forName("com.mysql.jdbc.Driver");
  32. return DriverManager.getConnection("jdbc:mysql://localhost:3306/ticket_system", "user", "password");
  33. }
  34. }

他包含了一个静态方法,他的职责是运行我们的事务和在异常情况下回滚.

我创建了一个简单的票务系统去展示TransactionHandler是怎么样和lambda一起工作的.

首先是一个成功的事务:

  1. @Test
  2. public void testSuccessfulPurchase() throws Exception {
  3.  
  4. TransactionHandler.runInTransaction(connection -> {
  5.  
  6. int ticketId = findAvailableTicket(connection);
  7.  
  8. reserveTicket(ticketId, connection);
  9. markAsBought(ticketId, connection);
  10. });
  11.  
  12. assertEquals(getNrOfTicketsIn(TicketState.AVAILABLE), 9);
  13. assertEquals(getNrOfTicketsIn(TicketState.RESERVED), 0);
  14. assertEquals(getNrOfTicketsIn(TicketState.BOUGHT), 1);
  15. }

控制台输出:

  1. Starting transaction
  2. Reserving ticket with id 1
  3. Marking ticket with id 1 as bought
  4. Committing transaction

然后是失败的事务:

  1. @Test
  2. public void testFailedPurchase() throws Exception {
  3.  
  4. TransactionHandler.runInTransaction(connection -> {
  5.  
  6. int ticketId = findAvailableTicket(connection);
  7.  
  8. reserveTicket(ticketId, connection);
  9. throw new IllegalStateException("Not approved credit card");
  10. });
  11.  
  12. assertEquals(getNrOfTicketsIn(TicketState.AVAILABLE), 10);
  13. assertEquals(getNrOfTicketsIn(TicketState.RESERVED), 0);
  14. assertEquals(getNrOfTicketsIn(TicketState.BOUGHT), 0);
  15. }

这个测试预定了一张票,然后抛出异常,触发回滚取消预约;

控制台输出:

  1. Starting transaction
  2. Reserving ticket with id 1
  3. Not approved credit card
  4. Rolling back...

lambda表达式的处理方式是简洁优雅的,而匿名内部类需要创建类并实例化他,你不觉得他有些太罗嗦了吗?

留意我们是如何使用lambda表达式作为一个工具去测试TransactionHandler的每个方面

你能在这里找到完整的例子 GitHub

*英文链接:deadCodeRising

*原创译文

[译]lambda表达式对 SAM (单个抽象方法类)type的处理方式的更多相关文章

  1. Java 终于有 Lambda 表达式啦~Java 8 语言变化——Lambda 表达式和接口类更改【转载】

    原文地址 en cn 下载 Demo Java™ 8 包含一些重要的新的语言功能,为您提供了构建程序的更简单方式.Lambda 表达式 为内联代码块定义一种新语法,其灵活性与匿名内部类一样,但样板文件 ...

  2. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_03 过滤器_2_FileNameFilter过滤器的使用和Lambda表达式

    复制一份上一节的代码 匿名内部类的形式 FilenameFilter 只有一个Accept方法.这样我们就可以使用lambda表达式 lambda表达式的前提条件 参数类型和,返回的大括号 都可以省掉 ...

  3. jdk8 lambda表达式总结

    Java8 lambda表达式10个示例   1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnab ...

  4. 接口和lambda表达式笔记

    接口 接口是双方,即服务提供方和想让它们的对象对服务是可用的那些类,之间约定的一种机制. 声明一个接口 public interface IntSequence{ //不提供实现,则该方法为抽象方法, ...

  5. 07_Java8新增的Lambda表达式

    [Lambda表达式概述] Lambda表达式支持将代码块作为方法参数,Lambda表达式允许将使用简洁的代码来创建只有一个抽象方法的接口的实例.(这种接口称为函数式接口) [入门实例] packag ...

  6. C++11中新特性之:lambda 表达式

    首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-i ...

  7. Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等

    一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接 ...

  8. Java 8 Lambda表达式,让你的代码更简洁

    Lambda表达式是Java 8一个非常重要的新特性.它像方法一样,利用很简单的语法来定义参数列表和方法体.目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift等都已经支持La ...

  9. Java 常用的几个lambda表达式

    Lambda表达式是Java 8一个非常重要的新特性.它像方法一样,利用很简单的语法来定义参数列表和方法体.目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift,C#等都已经支 ...

随机推荐

  1. 【转】H5 - HTML5新增标签

    下面分别是传统的div+css的页面布局方式 下面是HTML5布局方式: 是不是精简了很多呢  现在来说说图片中出现的标签: 结构标签:(块状元素) 有意义的div artical 标记定义一篇文章  ...

  2. Spring定时器调用Hibernate方法无法获得SessionFactory的解决办法

    由于在Spring定时器中无法通过注解的方式获取bean,因此需要通过原生的方式获取.获取session的方式如下: WebApplicationContext wac = ContextLoader ...

  3. 使用github同步网站

    今天刚刚完成了自己的一个小项目,想把他上传到服务器上,想到到我使用的Visual Stdio Code具有git功能,于是想到使用github作为代码仓库来同步代码. 大体步骤分为这几步:创建远程代码 ...

  4. Mac下使用Charles抓包Android

    原文地址:http://fanjiajia.cn/2018/11/21/Mac%E4%B8%8B%E4%BD%BF%E7%94%A8Charles%E6%8A%93%E5%8C%85Android/ ...

  5. 第一个Spring小程序实战

    ps:本文偏向原理和操作性,原理适合于任何编译器. 支持Spring入门,目的是在xml文件里面装配相关bean(java对象),并实现获取.(IOC) 一.先建立一个Spring新项目,添加mave ...

  6. JQuery实现的智能表单提示

    实现一个类似如此效果的表单验证:

  7. CodeForces Round #521 (Div.3) E. Thematic Contests

    http://codeforces.com/contest/1077/problem/E output standard output Polycarp has prepared nn competi ...

  8. SpringMVC-01-宏观上把握SpringMVC框架

    springmvc是一个基于mvc的web框架,是spring框架的一个模块,所以springmvc和spring无需通过中间整合层进行整合.我们先来看下spring的一个架构模型,看springmv ...

  9. 在Linux下调试Python代码的各种方法

    这是一个我用于调试或分析工具概述,不一定是完整全面,如果你知道更好的工具,请在评论处标记. 日志 是的,的确,不得不强调足够的日志记录对应用程序是多么的重要.您应该记录重要的东西,如果你的记录足够好的 ...

  10. [洛谷P3377]【模板】左偏树(可并堆)

    题目大意:有$n$个数,$m$个操作: $1\;x\;y:$把第$x$个数和第$y$个数所在的小根堆合并 $2\;x:$输出第$x$个数所在的堆的最小值 题解:左偏树,保证每个的左儿子的距离大于右儿子 ...