本記事は以下のツイートの翻訳転載です。
関数に多くの引数を渡したい場合どうするか、という内容になります。
2つのパターンが紹介されていますが、確かにどちらもよく見るなという印象です。
- 構造体を使用している例
- オプションパターンを使用している例
Golang Tip #22: 構造体やオプションパターンを使って関数のシグネチャをシンプルにする
Goで関数を設計するとき、多数のパラメータを渡す必要が出てくることがある。
これは関数の目的を曇らせ、特に同じ型のパラメータが含まれる場合、コードの維持が面倒になる。
物事を整理するために、2つの戦略を考えてみよう
- 構造体の活用
- オプションパターンの活用
1. 構造体
関数に渡したいパラメータを構造体に入れ込むことで、可読性を高めるだけでなく、引数の受け渡しを簡単にします。
どのような場合に使うのか?
- 関数に渡したいパラメータが多い場合
- 構造体のフィールド名に本質的にその目的を示すことで、コードを自己文書化したい場合
- デフォルト値を簡単に設定したり、オプションを柔軟に変更したい場合
このパターンを使用する場合、context.Context
は別のパラメータとして残し、構造体の中には含めるべきではない。
これは、リクエストスコープの値や有効期限(Deadline
)、キャンセルシグナルをコントロールするという、コンテキストのユニークな役割によるものです。
使用する際のちょっとしたヒント
- 構造体には後方互換性を持たせておくと、新しいフィールドを追加するときに既存の挙動を壊すことがない
- 構造体を使用する前に、常に構造体を検証できる
- 構造体を隠蔽し(unexported/privateにし)、
NewXXX()
関数を公開してデフォルト値を設定することを検討してください
2. オプションパターン
このメソッドはGoの関数機能を利用し、任意の数のオプションをよりクリーンな方法で渡すことができます。
次のような場合に最適です
- 関数に高度な設定が必要な場合
- 一部の必要な設定パラメータのみ渡したいような場合
- 簡潔な関数呼び出しを実現したい場合
デフォルト値を設定するのは、構造体を使用するよりも簡単です。隠蔽する必要はなく、ConnectToDatabase
にデフォルト値を直接記述するだけです。