在阅读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. winform自动最大化(在不同分辨率情况下)

    load函数末尾加: System.Drawing.Rectangle rec = Screen.GetWorkingArea(this); int SH = rec.Height; int SW = ...

  2. $this是什么意思-成员变量和局部变量的调用

    关键字$this代表其所在的当前对象 使用当前对象的属性和方法 $this->取值 方法内的局部变量 不能用$this 关键字取值 /* 和java,c++相比 方法体内想访问调用者的属性,必须 ...

  3. PAT 1086 就不告诉你

    https://pintia.cn/problem-sets/994805260223102976/problems/1038429065476579328 做作业的时候,邻座的小盆友问你:“五乘以七 ...

  4. exit和die的区别

    网上搜索die与exit两个函数的区别,大部分的"标准答案"都是说die是退出并释放内存,exit是退出但不释放内存. 这个解释显然是错的,PHP手册中已经说过"die ...

  5. JSP表单提交出现中文乱码的解决方法

    1)post方式 在servlet的doGet( )  doPost( )  中增加以下代码: response.setContentType("text/html;charset=utf- ...

  6. 【bzoj1263】[SCOI2006]整数划分 高精度

    题目描述 从文件中读入一个正整数n(10≤n≤31000).要求将n写成若干个正整数之和,并且使这些正整数的乘积最大. 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=10 ...

  7. Div+Css制作圆

    Div+Css制作四分之一圆主要是使用Css3.0中的border-radius这个圆角隐藏属性.利用这一属性,我们可以画圆,画半圆,四分之三圆,四分之一圆等.以后我会更新…… 如何使用border- ...

  8. [洛谷P3376]【模板】网络最大流(ISAP)

    C++ Code:(ISAP) #include <cstdio> #include <cstring> #define maxn 1210 #define maxm 1200 ...

  9. BZOJ3648 寝室管理 【点分治 + 环套树】

    3648: 寝室管理 Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 366  Solved: 152 [Submit][Status][Discus ...

  10. AOJ.502 不只是水仙花

    不只是水仙花 Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MB Total Submission: 1196 Submi ...