N0.11 関数オプションパターンを使わない
Config構造体
必須のパラメータは関数のパラメータとして渡し、オプションのパラメータはConfig構造体で渡す。
type Config struct {
Port int
}
func NewServer(addr string, cfg Config) {
...
}
これだとPortが入力されたゼロなのか初期値のゼロかを区別できないので *int
整数ポインタを使うとうまくいくが、クライアントにとって整数ポインタを提供するのは使いやすくないという欠点がある。
またデフォルト設定で利用したい場合でも空の構造体を渡す必要があるので見栄えが悪く、空の構造体を渡している意味を理解する必要がある。
httplib.NewServer("localhost", httplib.Config{})
ビルダーパターン
ConfigBuilder構造体を用意するパターンですがConfig構造体を使うのと同じデメリットが存在していたりするのでそういうのもあるのだなと認識して次へ。
関数オプションパターン
これが本命。このような書き方のパターンがあると知らなければ自分では辿りつかなかった実装パターンだと思いました。
UZABASEのエンジニアブログで実装している例がコーヒーを題材にしていて理解しやすかったので引用させてもらいます。
以下のコードは書籍から抜粋
type options struct {
port *int
}
type Option func(options *options) error
func WithPort(port int) OptionFunc {
return func(options *options) error {
if port < 0 {
return errors.New("port should be positive")
}
options.port = &port
return nil
}
}
func NewServer(addr string, opts ...Option) (*http.Server, error) {
}
自分はこういう関数型を作るっていう発想がなかなか出てこないのでまだGo脳にはなりきれていないなと感じます。
(WIP)
コメント