1. 前言
Payment Spring Boot 1.0.4.RELEASE已经发布,在项目的推广上也有了起色,越来越多的开发者开始尝试这个新东西。今天胖哥来分享一下这个项目中Lambda的使用心得,希望对你的学习和工作有所帮助。
2. 看清本质
❝
无论面对任何事,我们都要尽可能的看清其本质。
这句话不是什么名人大家说的,而是我中学的数学老师。他告诉我遇到数学题,不要立即埋头去做,先要分析这道题所涉及的知识点,这样才能快速领会这道题的立意。让我受用至今。
编程也是一样,遇到一个需求,先分析流程,把整个流程抽象化,然后再去填充细节。
就封装微信支付来说,不!封装第三方调用来说。一定是下面的流程:
第三方调用的本质
流程的抽象是我们解决问题的大前提。有了流程我们就能用代码进行抽象了。根据流程下面是 App 支付的一个实现:
public WechatResponseEntity<ObjectNode> appPay(PayParams payParams) {
// Consumer 如果要拿到结果返回只能通过这种方式消费 有点类似 setter
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.NATIVE, payParams)
//BiFunction 用来组织参数
.function(this::payFunction)
//TODO 这里可以增加一个Supplier 来指定请求的客户端
//Consumer 用来消费结果
.consumer(wechatResponseEntity::convert)
//执行请求
.request();
return wechatResponseEntity;
}
包含了两个Lambda,通过注释我们能够非常明确地知道流程是怎么样的。
3. Lambda 的实践
接着我们就可以根据上面的流程来进行深入了解细节了。看看如何在实际业务流程中来运用Lambda。
组织参数
组织参数目的就是为了第三方接口的调用,而且都要符合第三方 API 的要求。拿微信支付 APP 支付接口来举个例子,它的请求报文大致是这样的:
微信支付APP支付请求报文
如果我们记我们封装后调用的入参为
INPUT
,将
INPUT
按照上述接口进行组织满足微信 APP 支付接口的参数为
OUTPUT
。那么它们的转换关系其实就是下面的一个Lambda抽象:
INPUT -> OUTPUT
数学上为:
对应Java中的Lambda函数是
Function<INPUT>
。
但是在实际开发中需要根据接口的具体情况做不同的处理,需要引入包含请求方法(上图中的
POST
)和接口端点,记作
TYPE
,高中我们讲过函数替代法,我觉得这里可以用一用:
如果我们令 :
很容易推导出:
(TYPE,INPUT) -> OUTPUT
对应Java中的Lambda函数是
BiFunction<TYPE,INPUT>
,针对不同的
TYPE
实现
BiFunction<TYPE,INPUT>
就可以响应变化。
调用第三方接口
在Java开发中,无论你选择的请求方式是Spring Framework提供的
RestTemplate
或者反应式客户端
WebClient
,或者
OKHttp
都可以很方便地调用 Http 接口。也可以抽象,不管你用什么方法都是提供了一个调用工具,我们要拿工具来用就要
get
,因此非常适合Java中的
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Lambda式子为:
() -> T
不过目前Payment Spring Boot对于调用层还没有抽象的打算,如果考虑到抽象一定会用
Supplier<T>
去实现。
消费结果
最终我们都需要对调用获取的结果进行消费,宏观上只能消费一次。对应的Lambda式子:
(T) -> {}
对
T
进行消费是没有返回值的。就像吃一个苹果,吃完之后是不会立即有产物的,否则你要赶紧吃点