函数适配器这种语法比较特别,目前只在Golang中发现。其主要使用场景是当我们有一个接口(interface)时,一般需要定义多个Class然后实现该Interface的方法。
但是这个过程实际上是 Boring 的,如果我们定义的所有类只是想定义该接口的具体实现没有他们各自独特的方法,那么可以使用函数适配器来简化这个过程,用不同的函数来实现,这些函数函数名之间是不同的,但是函数参数、返回值和接口的定义是一致的。
net/http 中的使用
第一次看到函数适配器的使用,是在Golang的net/http库中,我们要定义一个Http服务,可以使用Mux复用器来指定URL对应的handler。
mux.Handle可以看到第二个参数是一个interface,这是我们常用的一种代码实现方法。
ServeHTTP幸好,函数适配器解决了这个问题。
我们看上面的代码,使用的 list 和 price 虽然函数名不一样,但是他们的函数签名(参数、返回值)是一样的。针对这种情况,我们可以通过函数适配器,将不同的方法转换为具体的一个接口实现。
http.HandlerFuncHandlerFunc另外针对该 适配器,定义其具体的接口实现方法(所以它能被当做接口的具体实现)最后,调用其被代理的函数传入相同的参数。
使用场景
在近期的开发工作中,我正好也遇到了类似的场景。我们在开发一个MQ的注册客户端,每次注册时都需要传入一个回调函数。因为需要注册的Key比较多,所以定义多次的注册操作,并且需要定义多个函数具体实现的struct,这个过程是比较繁琐的。
所以我使用了函数适配器,将所有的逻辑封装在一个统一的方法中,该方法接收一个需要被代理的函数,并且使用函数适配器将其转换接口可接受的函数,这简化了大量的代码,使得代码看起来更加的优雅。
具体的实现其实和 net/http 的类似,这里就不赘述了,如果工作中有类似的场景其实基于 net/http 的进行改造就可以了。