рд╣реЗрд▓реЛ, рд╣реЗрдмреНрд░! рдореИрдВ рдЖрдкрдХреЛ M├бrk S├бgi-Kaz├бr рджреНрд╡рд╛рд░рд╛ рд╕реНрдЯреЗрд░реЙрдпрдб рдкрд░ рд▓реЗрдЦ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВ ред
рд╕реНрд╡рдЪреНрдЫ рдФрд░ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдЧреЛ рдХреЗ рдкреНрд░рддрд┐рдорд╛рди рд╣реИрдВред рд╡рд╣ рдбреЗрд╡ рдЪреЗрдиреА рдФрд░ рд░реЙрдм рдкрд╛рдЗрдХ рджреНрд╡рд╛рд░рд╛ рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИ ред рдпрд╣ рдкреЛрд╕реНрдЯ рдЙрди рдкреНрд░рдерд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╢реБрд░реВ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЖрд╕рдкрд╛рд╕ рд░рд╣реА рд╣реИрдВредрдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫреЗ рдФрд░ рд╕реНрд╡рдЪреНрдЫ рдПрдкреАрдЖрдИ рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрднрд░рд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХрдИ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХреЗ рд╣реИрдВ (рдирд┐рд░реНрдорд╛рддрд╛, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛, рдмрд╕рдиреЗ рд╡рд╛рд▓реЗ, рдЖрджрд┐), рд▓реЗрдХрд┐рди рдЬрдм рдЖрдкрдХреЛ рджрд░реНрдЬрдиреЛрдВ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╡реЗ рдЦрд░рд╛рдм рдкрдврд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдРрд╕реЗ рдЕрдЪреНрдЫреЗ рдПрдкреАрдЖрдИ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВредрдкрд░рд┐рдЪрдп - рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдХреНрдпрд╛ рд╣реИрдВ?
рдЖрдорддреМрд░ рдкрд░, рдЬрдм рдЖрдк "рдСрдмреНрдЬреЗрдХреНрдЯ" рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ:obj := New(arg1, arg2)
(рдЖрдЗрдП рдЗрд╕ рддрдереНрдп рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░реЗрдВ рдХрд┐ рдЧреЛ рдореЗрдВ рдХреЛрдИ рдкрд╛рд░рдВрдкрд░рд┐рдХ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИрдВред)рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдкреАрдЖрдИ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЙрдкрд░реЛрдХреНрдд рдкрдВрдХреНрддрд┐ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдВ рдмрджрд▓ рджреЗрддреЗ рд╣реИрдВ:
obj := New(arg1, arg2)
obj := New(arg1, arg2, myOption1, myOption2)
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдореВрд▓ рд░реВрдк рд╕реЗ рдПрдХ рдЪрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рд╣реИрдВ рдЬреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рд╕рдордЧреНрд░ рдпрд╛ рдордзреНрдпрд╡рд░реНрддреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИред рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдкреНрд░рдХреГрддрд┐ рдХреЗ рдХрд╛рд░рдг, рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╡рд┐рдХрд▓реНрдк рдХреЗ, рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╡рд┐рдХрд▓реНрдк рдХреЗ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рднрд▓реЗ рд╣реА рдЖрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реЛрдВредрдкреИрдЯрд░реНрди рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдПрдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдЙрджрд╛рд╣рд░рдг (рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдмрд┐рдирд╛) рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:type Server struct {
addr string
}
func NewServer(addr string) *Server {
return &Server {
addr: addr,
}
}
рдЯрд╛рдЗрдордЖрдЙрдЯ рд╡рд┐рдХрд▓реНрдк рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:type Server struct {
addr string
timeout time.Duration
}
func Timeout(timeout time.Duration) func(*Server) {
return func(s *Server) {
s.timeout = timeout
}
}
func NewServer(addr string, opts ...func(*Server)) *Server {
server := &Server {
addr: addr,
}
for _, opt := range opts {
opt(server)
}
return server
}
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк API рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ рдФрд░ рдкрдврд╝рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ:
server := NewServer(":8080")
server := NewServer(":8080", Timeout(10 * time.Second))
server := NewServer(":8080", Timeout(10 * time.Second), TLS(&TLSConfig{}))
рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЖрд░рдВрднреАрдХрд░рдг рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
server := NewServer(":8080")
server := NewServerWithTimeout(":8080", 10 * time.Second)
server := NewServerWithTimeoutAndTLS(":8080", 10 * time.Second, &TLSConfig{})
server := NewServer(":8080", Config{})
server := NewServer(":8080", Config{ Timeout: 10 * time.Second })
server := NewServer(":8080", Config{ Timeout: 10 * time.Second, TLS: &TLSConfig{} })
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдкрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд▓рд╛рдн рд╕рдВрднрд╡рддрдГ рд╕реНрдкрд╖реНрдЯ рд╣реИ: рд╡реЗ рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рдкрдврд╝рдиреЗ / рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реЛрддреЗ рд╣реИрдВред рдлрд╝рдВрдХреНрд╢рдирд▓ рдкреИрд░рд╛рдореАрдЯрд░ рднреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдкреИрд░рд╛рдореАрдЯрд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рдореИрдВ рдФрд░ рднреА рдЕрдзрд┐рдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдЬрд╣рд╛рдБ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рдЙрдореНрдореАрджреЛрдВ рдкрд░ рдЦрд░рд╛ рдирд╣реАрдВ рдЙрддрд░ рд╕рдХрддреА рд╣реИредрдкрд░рд┐рдЪрдп рдореЗрдВ рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдкреВрд░рд╛ рдЗрддрд┐рд╣рд╛рд╕ рдкрдврд╝реЗрдВред (рдЕрдиреБрд╡рд╛рджрдХ рдХрд╛ рдиреЛрдЯ - рдбреЗрд╡ рдЪреЗрдиреА рдХрд╛ рдПрдХ рдореВрд▓ рд▓реЗрдЦ рд╡рд╛рд▓рд╛ рдмреНрд▓реЙрдЧ рд╣рдореЗрд╢рд╛ рд░реВрд╕ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдЗрд╕реЗ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╡реАрдкреАрдПрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓реЗрдЦ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдбреЙрдЯрдХреЙрдо 2014 рдкрд░ рдЙрдирдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХреЗ рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИ )рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдЕрднреНрдпрд╛рд╕
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рджрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рдХреБрдЫ рдирд╣реАрдВ рд╣реИрдВред рд╕рд░рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓рдЪреАрд▓рд╛рдкрди рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдмрдбрд╝реА рдХреНрд╖рдорддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдкреНрд░рдерд╛рдПрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЖрд╕рдкрд╛рд╕ рджрд┐рдЦрд╛рдИ рджреА рд╣реИрдВред рдиреАрдЪреЗ рдореИрдВ рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд╛рди рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдореИрдВ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдФрд░ рдЙрдкрдпреЛрдЧреА рдкреНрд░рдерд╛рдУрдВ рдкрд░ рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВредрдореБрдЭреЗ рдИрдореЗрд▓ рдХрд░реЗрдВ рдЕрдЧрд░ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣реА рд╣реИредрд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдкреНрд░рдХрд╛рд░
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп рдЖрдк рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реИрдХрд▓реНрдкрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВ:
type Option func(s *Server)
рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдПрдХ рдмрдбрд╝реЗ рд╕реБрдзрд╛рд░ рдХреА рддрд░рд╣ рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдкреНрд░рдХрд╛рд░ рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдЕрдзрд┐рдХ рдкрдардиреАрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:func Timeout(timeout time.Duration) func(*Server) { }
func NewServer(addr string, opts ...func(s *Server)) *Server
func Timeout(timeout time.Duration) Option { }
func NewServer(addr string, opts ...Option) *Server
рд╡рд┐рдХрд▓реНрдк рдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдХрд╛ рдПрдХ рдФрд░ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рдЧреЛрдбреЛрдХ рд╕реНрдерд╛рди рд╡рд┐рдХрд▓реНрдк рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд╣рдд рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ:
рд╡рд┐рдХрд▓реНрдк рдкреНрд░рдХрд╛рд░ рд╕реВрдЪреА
рдЖрдорддреМрд░ рдкрд░, рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ рдПрдХрд▓ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрд╢рд╛ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдХрдИ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╕рдордп рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИ:defaultOptions := []Option{Timeout(5 * time.Second)}
server1 := NewServer(":8080", append(defaultOptions, MaxConnections(10))...)
server2 := NewServer(":8080", append(defaultOptions, RateLimit(10, time.Minute))...)
server3 := NewServer(":8080", append(defaultOptions, Timeout(10 * time.Second))...)
рдпрд╣ рдмрд╣реБрдд рд╣реА рдкрдардиреАрдп рдХреЛрдб рдирд╣реАрдВ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдмрд┐рдВрджреБ рдЕрдиреБрдХреВрд▓ рдПрдкреАрдЖрдИ рдмрдирд╛рдирд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕реЗ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рд╣рдореЗрдВ рдмрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ [] рд╡рд┐рдХрд▓реНрдк рдХреЛ рд╕реНрд▓рд╛рдЗрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
func Options(opts ...Option) Option {
return func(s *Server) {
for _, opt := range opts {
opt(s)
}
}
}
рд╡рд┐рдХрд▓реНрдк рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕реНрд▓рд╛рдЗрд╕ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдмрди рдЬрд╛рддрд╛ рд╣реИ:defaultOptions := Options(Timeout(5 * time.Second))
server1 := NewServer(":8080", defaultOptions, MaxConnections(10))
server2 := NewServer(":8080", defaultOptions, RateLimit(10, time.Minute))
server3 := NewServer(":8080", defaultOptions, Timeout(10 * time.Second))
рд╕рд╛рде / рд╕реЗрдЯ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдЙрдкрд╕рд░реНрдЧ
рд╡рд┐рдХрд▓реНрдк рдЕрдХреНрд╕рд░ рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ, рдЯрд╛рдЗрдордЖрдЙрдЯ рдпрд╛ рдЕрдзрд┐рдХрддрдо рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╡рд┐рдкрд░реАрддред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рд░реНрд╡рд░ рдкреИрдХреЗрдЬ рдореЗрдВ, рдЖрдк рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рди рд╣реЛрдиреЗ рдкрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ):type Logger interface {
Info(msg string)
Error(msg string)
}
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд▓реЙрдЧрд░ рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рдХрд▓реНрдк рдирд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк рд╡рд┐рдХрд▓реНрдк рдХреЛ LoggerOption рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдЕрдиреБрдХреВрд▓ рдирд╛рдо рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдПрдХ рд╡рд╛рдХреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╢рдмреНрдж: WithLogger рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрддрд╛ рд╣реИредfunc WithLogger(logger Logger) Option {
return func(s *Server) {
s.logger = logger
}
}
NewServer(":8080", WithLogger(logger))
рдПрдХ рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдПрдХ рдФрд░ рдЖрдо рдЙрджрд╛рд╣рд░рдг рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд╣реИ:type Server struct {
whitelistIPs []string
}
func WithWhitelistedIP(ip string) Option {
return func(s *Server) {
s.whitelistIPs = append(s.whitelistIPs, ip)
}
}
NewServer(":8080", WithWhitelistedIP("10.0.0.0/8"), WithWhitelistedIP("172.16.0.0/12"))
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рдХрд▓реНрдк рдЖрдо рддреМрд░ рдкрд░ рдореМрдЬреВрджрд╛ рд▓реЛрдЧреЛрдВ рдХреЛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдмрдЬрд╛рдп рдЙрдиреНрд╣реЗрдВ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреЗред рдпрджрд┐ рдЖрдкрдХреЛ рдореМрдЬреВрджрд╛ рд╕реЗрдЯ рдорд╛рдиреЛрдВ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд╡рд┐рдХрд▓реНрдк рдирд╛рдо рдореЗрдВ рд╕реЗрдЯ рд╢рдмреНрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:func SetWhitelistedIP(ip string) Option {
return func(s *Server) {
s.whitelistIPs = []string{ip}
}
}
NewServer(
":8080",
WithWhitelistedIP("10.0.0.0/8"),
WithWhitelistedIP("172.16.0.0/12"),
SetWhitelistedIP("192.168.0.0/16"),
)
рдкреНрд░реАрд╕реЗрдЯ рдЯреЗрдореНрдкреНрд▓реЗрдЯ
рд╡рд┐рд╢реЗрд╖ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдЖрдорддреМрд░ рдкрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЙрдирдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╣реЛрддреЗ рд╣реИрдВред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд╕рд╛рде рд╕рдореВрд╣реАрдХреГрдд рдХрд┐рдП рдЧрдП рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрд╡ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рд░реНрд╡рд░ рдореЗрдВ рдЦреБрд▓реЗ рдФрд░ рдЖрдВрддрд░рд┐рдХ рдЙрдкрдпреЛрдЧ рдкрд░рд┐рджреГрд╢реНрдп рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЯрд╛рдЗрдордЖрдЙрдЯ, рдЧрддрд┐ рд╕реАрдорд╛, рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдЖрджрд┐ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рд╕реЗ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред
func PublicPreset() Option {
return Options(
WithTimeout(10 * time.Second),
MaxConnections(10),
)
}
func InternalPreset() Option {
return Options(
WithTimeout(20 * time.Second),
WithWhitelistedIP("10.0.0.0/8"),
)
}
рдпрджреНрдпрдкрд┐ рдкреНрд░реАрд╕реЗрдЯ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд╡реЗ рд╕рдВрднрд╡рддрдГ рдЖрдВрддрд░рд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рдмрдбрд╝реЗ рдореВрд▓реНрдп рдХреЗ рд╣реИрдВ, рдФрд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рдЙрдирдХрд╛ рдореВрд▓реНрдп рдХрдо рд╣реИредрдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░рдХрд╛рд░ рдорд╛рди рдмрдирд╛рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░реАрд╕реЗрдЯ рдорд╛рди
рдЧреЛ рд╣рдореЗрд╢рд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╣реЛрддрд╛ рд╣реИред рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рд╢реВрдиреНрдп рд╣реИ, рдмреБрд▓рд┐рдпрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЧрд▓рдд рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрд╢рдХреНрдд рдореВрд▓реНрдп рдХрд╛ рдорддрд▓рдм рдЙрд╕рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдмрдЬрд╛рдп рдЕрд╕реАрдорд┐рдд рд╕рдордпрдмрд╛рд╣реНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдЕрд░реНрдерд╣реАрди рд╣реИ)редрдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░рдХрд╛рд░ рдорд╛рди рдПрдХ рдЕрдЪреНрдЫрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╢реВрдиреНрдп рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдШрдмрд░рд╛рд╣рдЯ рд╣реЛ рд╕рдХрддреА рд╣реИ (рдпрджрд┐ рдЖрдк рд╕рд╢рд░реНрдд рдЬрд╛рдВрдЪ рдХреЗ рд╕рд╛рде рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдХреЙрд▓ рдХреА рд░рдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)редрдЗрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдорд╛рди рд╕реЗрдЯ рдХрд░рдирд╛ (рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ) рдлреЙрд▓рдмреИрдХ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ:func NewServer(addr string, opts ...func(*Server)) *Server {
server := &Server {
addr: addr,
logger: noopLogger{},
}
for _, opt := range opts {
opt(server)
}
return server
}
рдореИрдВрдиреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░реАрд╕реЗрдЯ (рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдЗрд╕реЗ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рдорд╛рдирддрд╛ред рдпрд╣ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рд╣реИ:func NewServer(addr string, opts ...func(*Server)) *Server {
server := &Server {
addr: addr,
}
opts = append([]Option{DefaultPreset()}, opts...)
for _, opt := range opts {
opt(server)
}
return server
}
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рд╡рд┐рдХрд▓реНрдк
рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╡рд┐рдиреНрдпрд╛рд╕ рд╕рдВрд░рдЪрдирд╛ рд╣реЛрдирд╛ рд╢рд╛рдпрдж рдЙрддрдирд╛ рд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрднреА-рдХрднреА рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд╕реНрддреБ рдХреЛ рдмрдирд╛рдП рдЬрд╛рдиреЗ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рдмрдЬрд╛рдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:type Config struct {
Timeout time.Duration
}
type Option func(c *Config)
type Server struct {
config Config
}
рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдиреЗ рд╕реЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдореЗрдВ рд╕рднреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ:config := Config{
Timeout: 10 * time.Second
}
NewServer(":8080", WithConfig(config))
рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ:config := Config{
Timeout: 10 * time.Second
}
NewServer(":8080", WithConfig(config), WithTimeout(20 * time.Second))
рдЙрдиреНрдирдд рдЯреЗрдореНрдкрд▓реЗрдЯ
рджрд░реНрдЬрдиреЛрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдк рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИред рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рд╕рдорд░реНрдерди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВредрдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:type Timeout time.Duration
NewServer(":8080", Timeout(time.Minute))
(рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдорд╛рди рд░рд╣рддрд╛ рд╣реИ)рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрджрд▓рдХрд░, рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
type Option interface {
apply(s *Server)
}
рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрдИ рдирдП рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рджрд░рд╡рд╛рдЬрд╛ рдЦреБрд▓рддрд╛ рд╣реИ:рд╡рд┐рднрд┐рдиреНрди рдирд┐рд░реНрдорд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдПрдХ рд░реИрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд┐рдирд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
type Timeout time.Duration
func (t Timeout) apply(s *Server) {
s.timeout = time.Duration(t)
}
рд╡рд┐рдХрд▓реНрдкреЛрдВ рдФрд░ рд╡рд┐рдиреНрдпрд╛рд╕ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА (рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рджреЗрдЦреЗрдВ) рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
type Options []Option
func (o Options) apply(s *Server) {
for _, opt := range o {
o.apply(s)
}
}
type Config struct {
Timeout time.Duration
}
func (c Config) apply(s *Server) {
s.config = c
}
рдореЗрд░рд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкрд╕рдВрджреАрджрд╛ рдХрдИ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ:
type ServerOption interface {
applyServer(s *Server)
}
type ClientOption interface {
applyClient(c *Client)
}
type Option interface {
ServerOption
ClientOption
}
func WithLogger(logger Logger) Option {
return withLogger{logger}
}
type withLogger struct {
logger Logger
}
func (o withLogger) applyServer(s *Server) {
s.logger = o.logger
}
func (o withLogger) applyClient(c *Client) {
c.logger = o.logger
}
NewServer(":8080", WithLogger(logger))
NewClient("http://localhost:8080", WithLogger(logger))
рд╕рд╛рд░рд╛рдВрд╢
рджрд░реНрдЬрдиреЛрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрд╡рдЪреНрдЫ рдФрд░ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рдПрдкреАрдЖрдИ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИред рдпрджреНрдпрдкрд┐ рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡рд┐рдиреНрдпрд╛рд╕ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд▓рдЪреАрд▓рд╛рдкрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреНрд▓реАрдирд░ рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред