SSブログ

抽象化と見立て

注意: この記事で書くことはある種の与太話です。

システムだとかライブラリだとか設計においては、2つ以上のよく似たものを(そしてそれほど似ていないものも)統一的に取り扱えるようにするということがしばしば行われる。思うに、その統一化をどのようなスタイルで行うかというところに、設計者の感性がもっとも良く現れる。

この統一化には大きく言って二種類の思想があるように思われる。ここでは一方を「抽象化」、もう一方を「見立て」と呼ぶことにする。(なお、ここでは抽象化という言葉の指す意味を狭い形でしか用いていないと思う)

前者では、よく似た概念 A と B の取り扱いを統一化するために A と B の共通部分を抽象した概念 C を導入して A と B は C の具体的な現れであるとする。これはしばしば段階的な構造をとる。Java を大して知らない私の印象論によると Java の標準ライブラリはこの種の注意深い設計にあふれている。クラスベースで継承が使えるオブジェクト指向言語はこうした設計を直接にサポートしているともいえる。

後者の方法では、同じ状況で「B を A に見立てる」。最も顕著な例は UNIX の「ファイル」だ。そこでは本来ファイルではない多くのものをファイルと見立てて取り扱う。

Windows Powershell ではいくつかの概念を旧来より Windows にあった「ドライブ」に見立てて取り扱いを統一化している。例えば PowerShell で環境変数の一覧を取得する方法の一つは cd Env: で Env: に移動して dir コマンドを叩くことだ。このドライブのように見えるものは総称してプロバイダと呼ばれるが、プロバイダに対して cd や dir といったコマンドを従来の用途を超えて使いまわすことができる。

Oracle では「ビュー」という本来は背後にテーブルの存在を前提とした概念を使ってパフォーマンス情報などの取得を行う(V$ ビューに対して select 文を発行する)。

Common Lisp では with-output-to-string マクロを使うことにより、出力ストリーム書き込み関数で文字列の構築を行うことができる。

Ruby の Array クラスは配列をキュー、スタック、集合、連想配列といったものに見立てて使うための多くのメソッドを備えている。

見立ての設計はアドホックであり、いびつである。UNIX でファイル扱いされたものがファイルとしての性質の全てを持っているわけではない。例えばそれは書き込み不能かもしれない。また PowerShell のプロバイダの全てがその下にディレクトリのような階層構造を持っているわけではない。Ruby の Array クラスは集合として取り扱うにはいろいろ中途半端すぎる。

抽象化は一般性があり、美しく、おそらくは維持しやすい。この性質の一部はおそらく A と B を「公平に」扱ったことによる。

見立ての方法は A を特別に扱い、B に対して不公平である。A を取り扱う方法はこれまでどおり何のペナルティも無いが、B は A に合わせた、必ずしも B を扱う最適ではないかもしれない方法で取り扱われることになる。(不公平な設計はある意味で公平な設計よりも注意深さが必要となる。特別扱いされるものは「よく使われるもの」で無ければいけないからで、この見極めを誤ると悲惨なことになるだろう)

一方で「公平」な設計は公平性の代償として A と B を「同じくらい面倒」な手段で取り扱う。Java の入出力ライブラリが貶められる理由は多分これによる(やはり印象論)。ただしこれはあくまで傾向の話で、理屈上は適切なラッパーやエイリアスやシンタクスシュガーといったものによって補うことはできるだろうと思う。

不公平な設計は対称性を捨てる代わりに、典型的なものをより accessible にし、単純なやり方で扱う。これは多分人間の言語の成り立ちにも少し似ている。

nice!(1)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 1

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。