在阅读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的处理方式的更多相关文章

  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. HDU 4587 TWO NODES(割点)(2013 ACM-ICPC南京赛区全国邀请赛)

    Description Suppose that G is an undirected graph, and the value of stab is defined as follows: Amon ...

  2. 二分图的最大匹配——Hopcroft-Karp算法

    http://blog.csdn.net/wall_f/article/details/8248373

  3. 详细讲解Java中方法的重载和重写

    首先讲讲方法的重载: Java的重载就是在类中可以创建多个方法,它们具有相同的名字,但是却有不同的参数. 判断是否重载只有两个条件: 1)相同的方法名 2)不同的参数 具体为: A.方法参数类型不同 ...

  4. .aspx文件和.aspx.cs文件的区别与联系

    http://zhidao.baidu.com/link?url=_SNw0EHJ8Wg__KanJrKQM3tVEUeFnVilZ6GGIN8ab69RLuyOWD__WyZb7Zb9dJjwDnL ...

  5. lnmp1.4,400,500,错误

    Thinkphp5或其他主流框架,入口文件未放在根目录下,比如Thinkphp5 入口文件放在/public/index.php vhost需要指向/public目录 一键安装包通常会报 open_b ...

  6. 如何在MyEclipse下查看JDK源代码

    在MyEclipse中查看JDK类库的源代码~ 设置: 1.点 "window"-> "Preferences" -> "Java&quo ...

  7. div clear清除浮动产生的影响 被受影响的div加上清除浮动后 不会填充前一个div浮动后空出的位置

  8. 【bzoj1257】[CQOI2007]余数之和sum 数论

    题目描述 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数.例如j(5, 3)=3 m ...

  9. BZOJ4444 SCOI2015国旗计划(贪心+倍增)

    链上问题是一个经典的贪心.于是考虑破环成链,将链倍长.求出每个线段右边能作为后继的最远线段,然后倍增即可. #include<iostream> #include<cstdio> ...

  10. perl的Sys::Syslog模块(openlog,syslog,closelog函数,setlogsock)-自定义日志

    perl的Sys::Syslog模块(openlog,syslog,closelog函数,setlogsock)-自定义日志 http://blog.chinaunix.net/xmlrpc.php? ...