#APIの数はどうするべき??
先日、携わっているAPIの開発で公開するI/Fの数をどうするか決める際に、そのメリット/デメリットをまとめる機会がありました。
そこで出たまとめの内容について述べていきたいと思います。
まとめた内容を大きくわけるとこの2つ
I/Fを一つしか用意せず、渡すパラメータで挙動を変える方法
公開されるのは一つの関数のみ
挙動は渡されたパラメータから内部の別処理に分岐させるやり方
機能毎にI/Fを用意する方法
機能毎に関数を公開
挙動はそれぞれの関数で閉じるやり方
では、これらのメリット・デメリットについて考えてみます。
##I/Fを一つしか用意せず、渡すパラメータで挙動を変える方法(集約型)
###メリット
- APIを使用する側の呼び出し口が一つしかない
###デメリット
- APIを呼び出すためにパラメータを一旦共通の型へ変換する必要がある
- 呼び出し先でパラメータを共通の型から変換する必要がある
- 共通の型に変換するため間違ったパラメータを渡す可能性がある
- 呼び出し口が一つのためコード上で何をしたいのかわかりづらくなる(可読性の低下)
- 変更の影響範囲が広い(結合度が高い)
##機能毎にI/Fを用意する方法(分散型)
###メリット
- 変更の影響が限定的(結合度が低い)
###デメリット
- APIの数だけ呼び出し口が作成される
集約型のメリットはデメリットにある型変換(呼び出し先のパラメータ内容を意識する必要がある)を考えるとメリットとは言えないかもしれません…。
※WindowsDLLで開発された場合に、明示的なリンクで呼び出すときの格納ポインタが少なくて済むという考えが重視される場合はメリットとなりえる。
集約型と分散型で双方とも使用するAPIに期待する機能を考えたとき
意識せざるを得ないポイントは同じ気がします。この場合、差分があるとしたら上記メリットデメリットの1つにある結合度でしょうか。
可読性も一つの差分ですが、そこは分散型であったとしても命名規則によっては同じことになる可能性があるため結合度よりは差分が小さいと思います。
APIの特性上、更新や不具合修正がAPIユーザに与える影響を考えると結合度が高いAPIは望まれないでしょう。
続いてはそれぞれでの使用例を考えてみます。
#使用例で考える(イメージはC++です)
##[集約型]
-
APIのユーザ
APIが公開している構造体を作成
呼び出し関数のパラメータにキャストして関数を呼び出し -
API内部
内部関数に振り分け
内部関数固有の構造体にキャストして処理を実施
##[分散型]
-
APIのユーザ
APIで公開されている内容でAPI関数を呼び出し -
API内部
処理を実施
これもやりたいことは変わらないのに集約型だけ手順が増えてます。
#優れたAPIとは?
C++のためのAPIデザイン
この書籍では優れたAPIは何を備えるべきか記載されています。
その中でも
挙動を変えない
メソッド名を変えない
誤用しにくい
この3つを兼ね備えることがAPIユーザにとって使いやすいAPIになるのではないでしょうか。
長々と書いてきましたが、集約型でAPIを開発する、という選択はありえないなという認識です。
※他に集約型でないとこれができない!などありましたらコメントお願いします。