配置问题

1
2
3
4
5
6
7
8
type Server struct {
Addr string
Port int
Protocol string
Timeout time.Duration
MaxConns int
TLS *tls.Config
}

Go 不支持函数重载,需要使用不同的函数名来应对不同的配置选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func NewDefaultServer(addr string, port int) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, 100, nil}, nil
}

func NewTLSServer(addr string, port int, tls *tls.Config) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, 100, tls}, nil
}

func NewServerWithTimeout(addr string, port int, timeout time.Duration) (*Server, error) {
return &Server{addr, port, "tcp", timeout, 100, nil}, nil
}

func NewTLSServerWithMaxConnAndTimeout(addr string, port int, maxconns int, timeout time.Duration, tls *tls.Config) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, maxconns, tls}, nil
}

Config

1
2
3
4
5
6
type Config struct {
Protocol string
Timeout time.Duration
Maxconns int
TLS *tls.Config
}

非必需的选项放入 Config

1
2
3
4
5
type Server struct {
Addr string
Port int
Conf *Config
}

只需要一个 NewServer 函数

1
2
3
4
5
6
7
8
9
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)

Config 并非必需的,需要判断为 nil 还是 Config{}

Builder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
}
1
2
3
4
5
6
sb := ServerBuilder{}
server, err := sb.Create("127.0.0.1", 8080).
WithProtocol("udp").
WithMaxConn(1024).
WithTimeOut(30*time.Second).
Build()

Functional Options

函数式编程,类似与 Java 的 java.util.function.Consumer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package main

import (
"crypto/tls"
"time"
)

// 类似与 Java 的 Consumer
type Option func(server *Server)

type Server struct {
Addr string
Port int
Protocol string
Timeout time.Duration
MaxConns int
TLS *tls.Config
}

func Protocol(p string) Option {
return func(s *Server) {
s.Protocol = p
}
}

func Timeout(t time.Duration) Option {
return func(s *Server) {
s.Timeout = t
}
}

func MaxConns(n int) Option {
return func(s *Server) {
s.MaxConns = n
}
}

func TLS(t *tls.Config) Option {
return func(s *Server) {
s.TLS = t
}
}

func NewServer(addr string, port int, options ...Option) (*Server, error) {
srv := Server{
Addr: addr,
Port: port,
Protocol: "tcp",
Timeout: 30 * time.Second,
MaxConns: 1000,
TLS: nil,
}

for _, option := range options {
option(&srv)
}

return &srv, nil
}

func main() {
s1, _ := NewServer("localhost", 1024)
s2, _ := NewServer("localhost", 2048, Protocol("udp"))
s3, _ := NewServer("0.0.0.0", 8080, Timeout(300*time.Second), MaxConns(1000))

_ = s1
_ = s2
_ = s3
}
1
2
3
4
5
6
package java.util.function;

@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}