GO编程模式学习笔记——FUNCTIONAL OPTION

GO编程模式学习笔记系列为学习陈皓的GO编程模式系列文章记录与心得。
原文链接:GO 编程模式:FUNCTIONAL OPTIONS

首先FUNCTIONAL OPTIONS只是一种模式,并不是必须的,个人感觉和替代者比,也未见得优势多明显,了解这种模式可以在读代码或者用第三方库的时候更轻松。主要是使用这种模式会让你的代码更具有Go语言风格,让你散发着gopher的独特气质。

如果一个对象的初始化配置项众多,且有很多可以使用默认值,也可以自定义,那么就可以使用以下三种方式解决:

1.必填项和选填项分离
func NewServer(addr string, port int, conf *Config) (*Server, error) {
    //...
}

//Using the default configuratrion
srv1, _ := NewServer("localhost", 9000, nil) 

conf := ServerConfig{Protocol:"tcp", Timeout: 60*time.Duration}
srv2, _ := NewServer("locahost", 9000, &conf)

其中addr和port是必填项,conf是选填,需要注意的是,如果conf只填充了一部分配置,在NewServer 中要给其他配置默认值。可以设置一个全是默认值的对象, 替换用户传入的部分。可能会有很多nil或者默认值的判断,所以还是有点烦的。

2.builder模式
//使用一个builder类来做包装
type ServerBuilder struct {
  Server
}

func (sb *ServerBuilder) Create(addr string, port int) *ServerBuilder {
  sb.Server.Addr = addr
  sb.Server.Port = port
  //其它代码设置其它成员的默认值
  return sb
}

func (sb *ServerBuilder) WithProtocol(protocol string) *ServerBuilder {
  sb.Server.Protocol = protocol 
  return sb
}

func (sb *ServerBuilder) WithMaxConn( maxconn int) *ServerBuilder {
  sb.Server.MaxConns = maxconn
  return sb
}

func (sb *ServerBuilder) WithTimeOut( timeout time.Duration) *ServerBuilder {
  sb.Server.Timeout = timeout
  return sb
}

func (sb *ServerBuilder) WithTLS( tls *tls.Config) *ServerBuilder {
  sb.Server.TLS = tls
  return sb
}

func (sb *ServerBuilder) Build() (Server) {
  return  sb.Server
}

使用

sb := ServerBuilder{}
server, err := sb.Create("127.0.0.1", 8080).
  WithProtocol("udp").
  WithMaxConn(1024).
  WithTimeOut(30*time.Second).
  Build()

如果说config模式的实现还确实有些不够专业的话,builder模式已经足够好了。作者看这个builder对象不顺眼,但是个人感觉没啥问题,也不用为了宣扬一种设计模式而贬低另外一种。

3.FUNCTIONAL OPTIONS模式
type Option func(*Server)

func Protocol(p string) Option {
    return func(s *Server) {
        s.Protocol = p
    }
}
func Timeout(timeout time.Duration) Option {
    return func(s *Server) {
        s.Timeout = timeout
    }
}
func MaxConns(maxconns int) Option {
    return func(s *Server) {
        s.MaxConns = maxconns
    }
}
func TLS(tls *tls.Config) Option {
    return func(s *Server) {
        s.TLS = tls
    }
}
s1, _ := NewServer("localhost", 1024)
s2, _ := NewServer("localhost", 2048, Protocol("udp"))
s3, _ := NewServer("0.0.0.0", 8080, Timeout(300*time.Second), MaxConns(1000))

解决了使用 Config 对象方式 的需要有一个config参数,但在不需要的时候,是放 nil 还是放
Config{}的选择困难,也不需要引用一个Builder的控制对象,直接使用函数式编程的试,在代码阅读上也很优雅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值