在阅读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. sysctl -P 报错解决办法 error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key

    error: "net.bridge.bridge-nf-call-ip6tables" is an unknown keyerror: "net.bridge.brid ...

  2. android-ViewList的通用ViewHold

    在写ViewList的时候要写Adapter的时候,经常大量的代码都是差不多的. 1 ViewHold 2 if(convertView ==null ){}else{} 3 setTag 4 FIn ...

  3. 团队作业4——第一次项目冲刺(Alpha版本)-第一篇

    第一次项目冲刺——第一阶段 今天我们在宿舍开了个会,每个人都斗志昂扬的.撸起袖子加油干! 分工讨论 团队成员 任务 郭达  完成博客随笔和leangoo 刘德培  设计好数据库 石浩洋  搭建好LAM ...

  4. [剑指Offer] 12.数值的整数次方

    [思路1]递归 class Solution { public: double Power(double base, int exponent) { ){ /base; exponent = -exp ...

  5. HTML5<canvas>标签:简单介绍(0)

    <canvas> 标签是 HTML 5 中的新标签,像所有的dom对象一样它有自己本身的属性.方法和事件, 其中就有绘图的方法,js能够调用它来进行绘图 ,最近在研读<html5与c ...

  6. 【题解】IOI2005River 河流

    一节语文课想出来的玩意儿,调了几个小时……可见细心&好的代码习惯是有多么的重要 (:へ:) 不过,大概竞赛最令人开心的就是能够一点一点的感受到自己的进步吧,一天比一天能够自己想出更多的题,A题 ...

  7. [bzoj1052] [HAOI2007]覆盖问题

    Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L * L的正方形塑料薄膜 ...

  8. dnsmasq-2.48没有ipset特性,安装dnsmasq-2.71来支持ipset

    iptables只能根据ip地址进行转发,不能识别域名,而dnsmasq-full不仅可以实现域名-IP的映射,还可以把这个映射关系存储在ipset中,所以使用dnsmasq+ipset就可以实现ip ...

  9. bzoj

    准确率爆棚啊,然而

  10. [poj 3261]后缀数组+滑窗最小值

    题目链接:http://poj.org/problem?id=3261 这个是可以交叉的重复串,所以用height就可以了,但是题目说让重复k次以上,也就是直接做一个k-1长度的滑窗最小值,从这些最小 ...