在阅读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

*原创译文

最新文章

  1. 3.python算法之完全数
  2. AD域服务器|两台DC无法进行复制同步
  3. p235习题2
  4. eclipse格式化代码末班修改
  5. 第三百四十四天 how can I 坚持
  6. [android]fmodex在某些android设备上声音延迟Latency
  7. app图标和启动页设置
  8. HTML——JAVASCRIPT——光棒效果
  9. 实践 config drive - 每天5分钟玩转 OpenStack(170)
  10. go语言获取变量的数据类型
  11. Android Studio创建/打开项目时一直处于Building“project name”Gradle project info的解决办法
  12. keepalived介绍
  13. verilog 之流水灯
  14. Linux 中用 dd 命令来测试硬盘读写速度
  15. CDH Spark-shell启动报错
  16. python自动化运维笔记2 —— IP地址处理模块IPy
  17. MySQL(二)MySQL的启动或链接失败
  18. golang:吐槽multipart的设计
  19. pthread_once重塑singleton模式
  20. Linux下的Mysql备份/恢复

热门文章

  1. POJ 2186 Popular Cows(强联通+缩点)
  2. Ext.Net学习网站
  3. 编译程序提示配置PKG_CONFIG_PATH
  4. php 文件上传失败
  5. ES 1.7安装ik分词elasticsearch-analysis-ik-1.2.5中文同义词实现
  6. Metrics+ElasticSearch+grafana
  7. bootstrap table表格属性、列属性、事件、方法
  8. 【转】The test form is only available for requests from the local machine 解决方法
  9. [洛谷P2824][HEOI2016/TJOI2016]排序
  10. [洛谷P4568][JLOI2011]飞行路线