用Option模式实现GO函数重载功能

787 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

有这样一个场景: 有一个名字为rpcMethod方法,需要在调用的时候,决定是否要指定"超时时间","集群信息","Host信息", 而这些参数的指定根据不同的场景,传入的配置都是不同的。

Java方法重载实现

Java的方法天然支持"重载","重载"的意思是指,函数的方法可以相同,函数的参数列表可以不同,这就是方法重载,利用方法重载可以 很轻松的实现上述功能。

public class RpcClass {
    
    public void rpcMethod(RequestParam req){
        // todo 
    }
    
    public void rpcMethod(RequestParam req, Integer timeout){
        // todo 
    }
    
    public void rpcMethod(RequestParam req, Integer timeout, String cluster){
        // todo 
    }
    
    public void rpcMethod(RequestParam req, Integer timeout, String cluster, String host){
        // todo 
    }
}

调用示例

什么都不指定

rpcMethod(req)

指定超时时间

rpcMethod(req,7000)

指定超时时间和集群信息

rpcMethod(req,7000,"default")

但是这种方式有一个问题,就是我想指定集群信息和host信息,那么因为没有定制的重载方法,我们只能通过调用最全的重载方法进行实现

public void rpcMethod(req,null,"default","127.0.0.1:1234")

超时时间传入了一个null,这会让人感觉比较奇怪,而且指定的信息也没有标识,不熟悉这个方法的开发人员并不熟悉后面的一些参数到底是用来干什么的。 可以看出,这种利用重载的方式去实现调用参数的指定,并不优雅

Option实现函数重载

Option是一种设计模式,java也可以使用,并不是Go语言的专利!!!

还是上面哪个例子,这里先定义一个配置信息结构体

type RpcConfig struct {
timeout time.Duration
cluster string
host    string
}

定义一个函数签名,这个函数用来给结构体的属性赋值

type Option func (config *RpcConfig)

针对结构体的参数信息,分别编写赋值函数

func Timeout(duration time.Duration) Option {
return func (config *RpcConfig) {
config.timeout = duration
}
}

func Cluster(cluster string) Option {
return func (config *RpcConfig) {
config.cluster = cluster
}
}

func Host(host string) Option {
return func (config *RpcConfig) {
config.host = host
}
}

Rpc方法的最后一个参数为可变长的Option

func RpcMethod(ctx context.Context, requestParam *RequestParam, ops ...Option) {
    // parse ops
    var rpcConf RpcConfig
    for _, op := range ops {
         op(&rpcConf)
    }
    // invoke rpc method
}

调用示例

什么都不指定

RpcMethod(ctx, req)

指定超时时间

RpcMethod(ctx, req, Timeout(7*time.Second))

指定超时时间和集群信息

RpcMethod(ctx, req, Timeout(7*time.Second), Cluster("default"))

指定集群信息和Host信息

RpcMethod(ctx, req, Cluster("default"),Host("127.0.0.1:1234"))

通过Option模式,可以很好指定Rpc方法的配置信息。可读性也很强