自作ライブラリのためのインタフェース

ある機能を持った自作のライブラリを作成しようとする場合、必ずユーザ定義のデータに関連した処理を必要とする。仮に、ユーザ定義のデータに依存した処理を含まない場合は、もっと汎用的なライブラリであり、そういうものはビルトインされている可能性が高い。


例えば、cosを計算するとか、あるデータに関連しない処理は、そう多くは書けない。ビルトインのデータ型しか処理を書くのに使用しないのであれば、ユーザ定義の処理を含まないが、そういうものはそうそう多くないし、あまり面白くない。


つまり、自作のライブラリを作成しようとした場合、必ずユーザ定義のデータに関する処理を含むと考えてよい。ところが、ユーザ定義に強く依存した処理は、汎用性がない。ユーザ定義に依存せずに書く方法としては、インタフェースを使用することだ。つまり、型が重要なのではなく、そのクラスにメソッドが定義されているかどうかが重要なのである。型は通常、抽象化する。


例えば、オブジェクト指向言語にあらかじめ用意されているインタフェースというのは、以下の2つだと思う。

  • Object型(全てのクラスのベースクラス)のメソッド
  • 演算子


逆に、自分で用意するインタフェースは、あるシグネチャ(メソッド名と引数並び)、および戻り値である。では、このインタフェースを自作のライブラリとしてどのように用意すべきであるか。


例えば、全て1つのインタフェースで全てのライブラリモジュールに必要なメソッドを詰め込むというのはどうだろう?もちろんライブラリの規模にもよるが、例えば、STLイテレータのように、階層的に実装しても面白い。


しかし、私の考えでは、ある意味どうでもよいと思う。と言うのも、例えば、Pythonのような動的言語で考えてみよう。動的言語では、もちろん、Javaのようなinterfaceを用意しておく必要はなく、Duck Typingによりオブジェクトのメソッドを動的に探すので、ライブラリ側の処理に必要なメソッドが実装されていればよい。もっと言えば、呼び出せる状態になっていさえすればよいと思う。つまり、interfaceのような明確な規定はなく、定義されているか否かである。


では、ライブラリのユーザ(クライアント)は、あるライブラリのメソッドに対して必要な(オブジェクトに用意しておくべき)メソッドは何かをどのように知るのであろうか?
今のところの私の考えでは、関数の先頭かどこかにコメントで書いておくか、ソースを直接読むか程度であると考えている。
別の考えでは、メソッドが定義されていない場合、例外を投げるなどを思いつくかもしれないが、動的言語では、言語自体が例外を投げてくれるし、静的言語では、もちろん、引数をインタフェースで書くので、コンパイル時に存在が保障されている。つまり、ライブラリ側では心配ご無用といった感じである。


そもそも、ライブラリ側は、汎用性が最重要なので、なるべく余計なことをしないというのが原則であるので、クライアント側に委譲できる処理は、ライブラリ側に持たせないようにすべきである。なぜライブラリ側(サプライヤ側)で色々規定しないかと言うと、もちろん色々規定すると汎用性が下がるからである。