APIの作成にあたって。提供する関数の引数は、オブジェクトにするのが良いのか。

最近、迷っていたこと。関数を作成する際、その引数は関数内部で使用するプロパティをひとつにまとめたオブジェクトにすべきか、それともプロパティを個別に引数として渡すべきか。

例えば、下記関数を作成したとしよう。

function api(arg1, arg2){
 ・・・・
}

このとき、途中で仕様が変更され、引数を増やす必要性がでてきた。
例えば、次のように。

function api(arg1, arg2, arg3){
 ・・・・
}

この場合、関数の引数を変更することによる影響は以下のようなことであろう。

  • 関数作成者のすべきこと
    • 作成するapi自体の修正
  • 関数利用者のすべきこと
    • 関数の呼び出し方法の修正。関数apiの使用者は、関数呼び出し時にarg3を引数に追加する必要がある

一方、関数apiの引数がオブジェクト1つである場合はどうだろうか。
つまり、

 var obj ={
  field1 : arg1,
  field2 : arg2
 }

となっていた場合、arg3を関数に渡す必要がでた際、関数の引数は変更する必要がなく、引数に渡すオブジェクトを変更すればよい。

 var obj ={
  field1 : arg1,
  field2 : arg2,
  field3 : arg3
 }

この場合の影響は以下のようなことであろう。

  • 関数作成者のすべきこと
    • 作成するapi自体の修正
  • 関数利用者のすべきこと
    • 関数に渡す引数の中身の修正

さて、この場合、api関数はどちらにすべきなのか。つまり、引数には複数の引数をまとめたオブジェクトを渡すように作成すべきか、それとも複数の引数をそれぞれ渡すような作りにすべきか。

ここまでの議論だと、どちらで関数を作成しても修正時の手間は大差なく、どちらでも良さそうに感じる。

ただ、引数をオブジェクト化すると下記利点がありそうだ。

  • 引数の順番を覚える必要がない
  • オプションのパラメータを省略できる。

一方で、下記欠点もありそう。

  • 引数のフィールド名を覚える必要がある。例えば、関数内部で、hogeオブジェクトのfilフィールドを使用する実装になっていた場合、関数の利用者はhogeオブジェクトにfilという名前でフィールドを追加する必要がある。

結論として、修正の手間は変わらなさそうだが、利用する際に引数の順番を覚えなくても良いため、引数はオブジェクトとして渡すのが良さそうだ。