輝々凛々

ガンバるってことは、素晴らしい事だ。

データ指向プログラミング2.0

まぁ、よく言われるオブジェクト指向の前身「データ指向プログラミング」とは違うお話。

プログラム、データ無ければ・・・

プログラムは何かの処理を行うものだけど、もちろんデータがなければ意味がない。たとえば画像を拡大するプログラムだって、画像データがなければ動けない。商品のないアマゾンやヤフオクと同じだ。

じゃあプログラムはデータをどう持って、どう扱うんだろうか。

データの持ち方。

たぶんプログラムがデータを持つ手段は、次の3つだ。

  1. ソースファイル中に埋め込む。
  2. プログラムとは別のファイルに持っておく。
  3. プログラムにくっつけて持っておく。
  4. プログラムが自身が作り出す。

4つ目は、ちと例外的で他の3つのどれかに属してもいいと思う。

さて、ここで圧倒的によく使われるのは2番目の「プログラムとは別のファイルに持っておく」でしょう(んー広い意味では、3番目が一番多いけど)。別のファイルに持っておけば、1つのプログラムだけでなく複数のプログラムから同じデータを共有化できる。共有化すれば、いろいろ問題も出てくるけれどファイルという単位でデータを利用する手段は、とても便利だ。

データの利用方法

では次にプログラムがどうやってデータを利用するのかを説明する。

まずデータをソースファイル中に持っておけば、もともと変数としてアクセスできるので問題はない。非常にシンプルで簡単だ。

次に2番目は飛ばして、3番目の「プログラムにくっつけて持っておく」では、これはリソースという形で比較的容易にアクセスできる(たいていは、そのデータのID番号でアクセスできる)。

4番目も、もちろん問題ない。自信が作り出すデータなら、自身でアクセスできる。

では、2番目の「プログラムとは別のファイルに持っておく」ではどうだろう。これだけは、ちょっと特殊だ。ファイルという単位は、もともとプログラム自身の外部にあるわけだから、そのアクセスは容易ではない。

まぁ、もちろんfopen()や、std::ifstream、java.io.InputStreamなどを使えばファイルを開いてデータ化して、プログラムからアクセスすることはできる。こんなのは昨今の高級言語なら当たり前のようにできる。

ファイルアクセス型プログラムの問題

だけど、どうだろう。プログラムにとって「データにアクセスする」ために「ファイルへアクセスする」ということは、何か本質は異なるものではないだろうか。プログラム自身がやりたいことは、データへのアクセスのはずである。ファイルがどんな物理領域に保存されていても関係ないし、ましてやその物理領域の制約事項なんてものも本来は関係ないはずだ。

そりゃもちろん、保存の際にはある程度の制約事項は仕方がないのはわかる。そうなれば当然、読み込みにも制限がかかるだろう。だけど、もう一度言う。プログラムにとってファイルアクセスだろうがメモリアクセスだろうが、プログラムが欲しいのはデータ。あくまでデータ。とことんデータ。

ファイル名でファイルにアクセスする手段が多いと思う。だけど、そのファイル名がUNICODEなのか、ASCIIなのか、そんなことをプログラマが気にしないとダメになる。ファイル名ごときで、データアクセスが阻害されるのだ。

事例

たとえば今、過去に作られたライブラリプログラムを使って最新の開発環境でアプリケーションプログラムの開発を進めるとしよう。ライブラリはファイル名を要求するのだが、そのファイル名をUNICODEで渡すことができない。そうするとアプリケーションではUNICODE文字列をASCII文字列に変換してからライブラリにファイル名を渡すことになる。

だけど、どうだろう。現実にUNICODEでしか表現できない文字というものもある。つまりそのライブラリにとってみれば、絶対不可侵のファイルだ。絶対にアクセスできない。

この話、マネージドC++あるいはC++/CLIで開発していれば、よくぶち当たる問題なのだ。よくASCII文字列やShift-JISコードに変換してライブラリを使う。ありふれた問題なのだ。だけど、誰も提起しない。古いライブラリを、そのままの仕様でごまかしながら使っているのだ。「時間がない」とか言って。

データ指向プログラミング2.0 - Data Oriented Programming 2.0

解決案は「ライブラリを最新環境で作り直す」のではない。それこそ時間がないし、最新環境が変わるたびに作り直す必要が出てくる。ひたすらリメイクし続けるゲームのようなものだ。

では、どうすればいいのだろうか。

もちろん、ファイルアクセスをやめれば問題はない。だけど現実にはそれは無理だ。ファイル単位でデータを持たないのなら、プログラム自身に含めるしかない。だけどそれはハードウェア的な制限・・というか無駄があるし、勿体無い。同じデータなのであれば、共有化させたい。

そこで、データ指向プログラミング2.0。プログラム、というか主にライブラリプログラムを作るときに注意する。ライブラリプログラムでは、ファイル名によるデータアクセスを禁止する。データはすべて、変数として扱える形で受け取る。そうすればライブラリプログラム側に足かせはなくなる(少なく・・かな)。

一方、アプリケーションプログラムではデータを用意するためのファイルアクセスを行う。このとき、さっきの事例のようにUNICODEファイル名をASCIIファイル名に変換してからアクセスするなんていう無駄な処理も無くなるし、文字コードを変換に失敗してアクセスできなかったファイルにもアクセスできるようになる。

データ指向プログラミング2.0の瑣末な問題点

ライブラリ開発者は、こう主張するだろう。「このライブラリを利用する人にとって、毎回毎回ファイルアクセスさせるのは煩わしくないか? それだったら、ファイルアクセスをライブラリに持っていた方がよくないか?」と。

だけどどうだろう。ファイルアクセスの仕方は、その時代によって、そのハードによって異なるのだから、ライブラリがファイルアクセスを持つことは止めたほうがいいと思う。何より、ライブラリ使用者(つまりアプリケーションプログラマ)が困るという状況より、ライブラリを組み込んだアプリケーションの使用者(つまりユーザー)を困らせることの方が問題ではないのか。

まぁ、実際問題ファイルアクセスが煩雑だというなら、そのファイルアクセス部分だけをライブラリから切り離したらいいのではないかと思う。もちろんライブラリがファイル名を持っていることで、エラー時により細かい情報を作り出せるかもしれない。けれどそれも、ライブラリの本質とは違う。「エラー」という状況は、ライブラリが本来すべき仕事とは別のものではないだろうか。

余計なまとめ

このデータ指向プログラミング2.0が気に入らなければ、それはそれでいいと思う。単に設計思想が異なるだけだ。相容れないプログラムだっただけだ。それは仕方ない。この世にあふれるライブラリから、別のものを見つけるだけだ。

だけど、現実に.NETでもJavaでも最近はファイルアクセスとデータ処理が別れててきている。もし新しいライブラリを書こうというのなら、どうかファイルアクセスはアプリケーションに任せて欲しい。ライブラリの容量に余裕があるのなら、ライブラリ内にファイルアクセスも含めていいかもしれない。だけど変数やクラスのインスタンスによるメモリアクセスの手段をなくさないで欲しい。

ほんとに、今、困っている。

関連記事

ツッコミの投稿


(ツッコミ非公開の場合はチェック)