osiire’s blog

ふしぎなそふとやさん

モジュールとクラスの使い分け方

OCamlにはモジュールとクラスがあります。この二つの仕組みは、直感的によく似た機能を持っているので、どう使い分けたらいいのか迷う時があります。そこで、モジュールとクラスの使い分け方について少しまとめてみます。

  • 基礎的なデータ/データ構造の場合

スタックとかキューとかグラフとか日付とか、内部構造を隠して操作だけを提供する、比較的基礎的な構造を作りたい場合です。この場合は、迷わずモジュールでいいです。ここをクラスにすると、バイナリメソッドで泣きます。

  • アプリケーションデータの場合

アプリケーション内で使う特定のデータ構造は、色々なデータの集合である事が多いので、大抵レコードになります。このレコードの代わりにクラスを使うのはありだと思います。逆に、これをモジュールでやると、内部型がないモジュールになって、オーバースペックな感じになります。もちろんレコードのままでいいなら、別にわざわざクラスにする必要はないです。

  • 実装を切り替えたいような構造の場合

アプリケーション内で比較的綺麗に抽象化が可能なデータ構造を扱う場合です。こういうやつは最初に型だけ定義しておいて、その型だけ利用しながらプログラムしていく感じになります。ここでクラスタイプを使いたくなる気持ちは分かるのですが、クラスタイプを使うなら型が一つか二つしかない簡単な場合に止めておいた方が無難です。型が三つも四つも関わってくるような構造を作り出すと、大抵型パラメータが多くなって破綻します。モジュールの場合は、型パラメーターは内部に抽象型として個別に持っておけば、後からwith type t = ...で単一化できるので気楽です。OCaml 3.12からはモジュールも第一級になったので、最早モジュールを使わない理由はありません。いざとなったらファンクターという高階な大鉈があるのも心強いです。

オブジェクト指向的なレコードの繋がりが既にあるライブラリを、下位構造としてラップして使うとかそういう場合です。例えばLablgtkとかocamljsとか。このラップをモジュールでやるのは斬新です。やってみた事ないです。型が合わないのは苦しいのですが、クラスでやった方が直感的だと思います。

という訳でまとめると、

1. クラスは便利なレコードという程度で使った方がいいと思うよ!あっ、ジェダイマスターは別ね。
2. 基礎構造や大域的な構造はモジュールで作るといいと思うよ!
3. オブジェクト指向な下位ライブラリをラップするならクラスがいいと思うよ!