3

I just learned about the Functional Options pattern in golang.
what are the benefits of using it over just allowing to pass a config struct and just overriding the default values provided in the config?

why do i need the complication of passing a function?

I saw here is that the advantages are that with this pattern you don't have to edit instantiations of classes if edit the structure of the config of a class.
however in cases of removed params for example, you still have to change every time you make an instance with the removed param. Even if you add a value to the config you would have to add it every where you want to use it, on a change of name you can change a config param only in the functional option (the presumed advantage), but then the function name would be misleading about which option it changes.

In which real life examples would i receive benefits from this pattern?


Explanation of the pattern

The Functional Options pattern in Go is a design pattern used to configure objects in a flexible and extensible way. It involves defining a set of options as functions that modify the state of an object. This pattern is particularly useful when you have a constructor or initializer function with many optional parameters.

moshevi
  • 139

1 Answers1

2

This looks to be a variant of the Builder Pattern. All the advantages of that pattern apply here.

Additionally, this is extensible, as you can pass anything with the signature func(*Server), it doesn't have to be something predefined by the author of Server.

E.g. if you were instantiating a number of servers that differed only in host, you could have:

func WithSharedSettings(s *Server) {
  server.WithPort(8080)(s),
  server.WithTimeout(time.Minute)(s),
  server.WithMaxConn(120)(s), 
  // or get these from config etc
}

func ConnectAll(hosts ...string) { for _, host := range hosts { svr := server.New( server.WithHost(host), WithSharedSettings, ) if err := svr.Start(); err != nil { log.Fatal(err) } } }

Another difference with a class-based builder is that these functions are also setters on the constructed object.

func ChangeHost(host string, s *Server) {
  server.WithHost(host)(s);
}
Caleth
  • 12,190