ユーザインタフェースと言語

毎日ブログ書く宣言から6日目。

今日のテーマは「ユーザインタフェースと言語」について。(連載中のプロダクトの機能検討はあとである程度まとめて続きを書きます)

本文を始める前にひとこと、僕は最近5年間くらいで、いつかブログに書こうと常々思っていたネタが両手に余るくらいあるのだが、それらの「持ちネタ」を全部放出したらまた書きたいネタが出てくるだろうか、それを確かめてみたいと最近思っている。今日書くのはそんな持ちネタの一つ。

単機能に特化したUI

何か機能をもったプログラムを書いて、それを多くの人に使ってもらうためにそこにGUI(今はほぼWeb一択だが)をつけるとき、みんなどういう風にUI設計をしているだろう?
一番素朴なやり方は、プログラムの機能ごとに入力データと出力データを洗い出して、それをGUI上の入力フォームと出力フォームの形に置き換えるというものだろう。そういうGUIは「イケてないけど、まぁ使えなくもない」レベルのものだが、プログラムがある固有のタスクを行うように作られているだけのとき、つまり一つの機能は一つの用途のために実装されているようなプログラム(もちろん1機能が1用途に対応していれば、プログラムに複数の機能が搭載されていても同様)の場合は、最低限のGUIとして受け入れられなくもないレベルではある。例えば、DVDの内容を吸い出してハードディスクに保存する「リッピング」という機能を持ったソフトがあるが、リッピングソフトのGUIとして、入力フォームに必要なファイル名や保存先のディレクトリなどを「キーボードでファイルのパスを入力する」形で指定して実行ボタンを押すというシンプルすぎるものでもまぁ使える。こういう種類のプログラムでより使いやすいGUIを作るならば、その固有のタスクにより特化したインタフェースを考えることが必要だ。例えば、GUIを起動するとDVDのアイコンとHDDのアイコンの2つが並んでいて、DVDアイコンをクリックするとDVDドライブをマウスで選択する画面になり(もしDVDの入ったドライブが一つしかなければそれが選ばれ)、HDDのアイコンをクリックすると保存先のディレクトリをマウスで選択する画面になり、それぞれ選択すると2つのアイコンの間にある矢印マークのボタンがが浮かび上がって、それを押すとリッピングがスタートする、といったGUIが考えられる。これはリッピングのタスクに特化しているぶん、ユーザにとっては迷いのないGUIになる。

幼児言葉の全体感

そうした「用途に特化したインタフェース」というのは、インタフェースに対応づけられたセマンティクスが「固有で全体的」だという意味で、いわば「幼児の言葉」のようなものだと思う(専門的には「初語」と呼ぶそうです)。「ママ」とか「マンマ」とか「ブーブ」とか、そういう言葉だ。そうした幼児の言葉は、大人の文法体系に照らし合わせれば「名詞」ということになるのかもしれないが、そこで指し示すものは大人が使う名詞の語よりももっと世界全体とくっついている。例えば、幼児が「ママ」という言葉を発するとき、ママという人格を指し示すだけではなく、ママにそばにいてほしいという願いとかお腹がすいたとか退屈だとかいった「自分の世界に全体的にまとわりついてる感情の揺らめき全体を、ママという方向に向けた感じ」を指している。したがって幼児は、ママという呪文を発するだけであとは受け身でそうした「ママにまつわる自分の望ましい感情的なプロセス」を享受できる。「お腹がすいた」という言葉を発する必要はなく、(それはママというプロセスに組み込まれているものなので)ママがふさわしいタイミングでどうにかしてくれるのだ。単機能に特化したインタフェースというのはそういう幼児言葉のセマンティクスに類似する。一つの機能を呼び起こせばあとは受け身でプロセスを享受できる。

このようにユーザインタフェースと言語は、人間の認識という観点でみると密接な対応関係がある。さて、そうすると幼児言葉から出発し、成長するにつれて扱う語彙が多様になり一つ一つの語が指し示す範囲は狭くなり、分化した語と語が再びつむぎあうことで「現実」と「想像」の両方の世界観が立ち上がってくるという人間の幼児から大人に至るまでの言語発達のプロセスは、ユーザインタフェースの分類にも同様に当てはめられそうだ。

感情の分化と言語発達

ここでちょっと話が脱線するが、人間が語彙を増やしていくときに感情的な成熟が重要な条件になっていることが上記の話で分かる。例えば、お腹がすいたのか、寂しいのか、感情が未熟で切り離されていない段階では「腹が減る」や「寂しい」という概念を認識することは出来ないだろう。仮にママが観察力を発揮して「あー、お腹がすいたねぇ」(=ほぼ当たり)という言葉を投げかけたとしても、「抱っこしてほしい」ときの感情との差があまりない状態だと、幼児は自分の感情の揺らぎを「お腹がすいたねぇ」という声にマッピングさせて覚えておくにはまだまだノイズが大きすぎるからだ。感情に区別がつくようになることと、概念の獲得は対応していると思う。そうした感情に区別がつくという感情の成熟プロセスは、程度の差はあれど大人になっても継続しているだろう。ただ大人の語彙体系ともなると、それぞれの語彙は感情的な揺らぎとかなり遠いところにはマッピングされているが、まったく感情と切り離されてはおらず遠く間接的に対応づいている。例えば「会議資料」いう言葉に込められるのは、資料を作ったり資料をやり取りしたりすることが自身の収入の変動に影響し、実際にそれが実現したときに起こるであろう自身の好悪の感情への期待もしくは恐れが、その会議資料という言葉のセマンティクスだ。たいていの大人の語彙は社会的な関係調整を間に挟んで自身に起こる感情と間接的に結びついているため、その介在する複雑な社会像がそのまま語彙の多様性となって表れているのだろう。

こうした言語発達のプロセスはユーザインタフェースにも当てはめられる。つまり発達すればするほどインタフェースは専門分化し、「直接の便益性を享受できる状態」との間に複雑なシステムが介在するようになる。と、ここで勘のいい人は分かっていると思うが、そう、最も発達したユーザインタフェースというのは「プログラミング言語」そのものだ。

2語文/3語文 : UNIXコマンド

子供の言語発達ではマンマやブーブといった初語の次にくるのは「ブーブきた」とか「ワンワンいた」という2語文や3語文だ。2語文はブーブきた、のような叙述的な文だけでなく「ママ、アイス」という命令的な文も含まれる。2語文や3語文は、それぞれ語を差し替えて文を作り直せる(「キリンさん、いた」とか「パパ、きた」とか)。これはユーザインタフェースでいうところのUNIXコマンドのようなものだ。UNIXコマンドのインタフェースは、コマンドや引数の組み合わせをユーザが指定することで所望の動作を実現させるものだからだ。このフェーズでのママという言葉のセマンティクスは、「ママ」と同時に発せられるさまざまな言葉(「アイス」とか)との組み合わせを期待させるものになっている。UNIXコマンドも同様に、各コマンドは「引数を伴ってプロセスとなる期待」がそのコマンドのセマンティクスとなっている。

さらに「2語文/3語文に続く言語発達」に対応する構造が「UNIXの哲学」に見られる。UNIXの哲学と呼ばれるものにはいくつか種類があるようだが、ユーザインタフェースという観点ではとくに以下の規範(エリックレイモンドによる規範から抜粋)が重要だ。

  • クリーンなインターフェースで接続されるシンプルなパーツを書け。(モジュール性)
  • 他のプログラムと接続できるようプログラムをデザインせよ。(合成のルール)
  • ポリシーをメカニズムから分離せよ。インターフェースをエンジンから分離せよ。(分割のルール)
  • シンプルさを求めてデザインせよ。複雑にしなければならない場合に限り、複雑さを加えよ。(シンプルさのルール)

つまり、ユーザに見せるインタフェースはメカニズムやエンジンといったプログラムの内部構造と分離させた形でデザインし、他のプログラムと振る舞いを合成できるようにし、ユーザにとって必要最小限の複雑さにとどめるという方法だ。2語文を話す子供は「ママ、アイス」と発して様子を見るというレベルでの語彙体系で十分だが、本当の内部構造(つまりママがどんな時にアイスを買ってくれるかには複雑なメカニズムがある)は、その単純な語彙体系を通して(言葉を繰り返し使っては結果を観察することで)あとから把握することになる。ユーザインタフェースも言語発達も、そうしたステップを踏んで次の段階へ進むことになる。

ちなみに、ここではコマンドインタフェースについて述べたが、GUIにおけるこのフェーズは、メニューを選ぶと、ダイアログが出てきて色々入力すると機能を実行できるというよくあるパターンに相当するだろう(そのパターンは大抵プログラム内部でコマンドパターンというデザインパターンで実装されているし)。メニューがUNIXコマンドに相当し、ダイアログで入力する項目がコマンドの引数に相当する。

大人の使う言葉 : プログラミング言語

既に言及してしまったが、ユーザインタフェースの発達過程の最終地点はプログラミング言語そのものになる。UNIXコマンドでパイプラインで処理を合成するような限定的な言語体系から、RubyJavaのような通常のプログラミング言語に至るまで色々な階層がありうる。ここで(ややこしいけど)最も高い階層に位置しているのはC言語アセンブラ言語だ。Cやアセンブラは最も汎用性が高く他の言語を作り出すことができるからだ。RubyはCと比べるとよりドメイン特化的なインタフェースである。ドメインに特化すればするほど言語発達でいうところの「子供返り/幼児返り」の方向へ進むことに相当し、ユーザにとっての簡易性が増す。つまり、プログラムを書くという行為はここまで述べてきたインタフェースの発達過程でいうところの、階層の高いところから低いところへ、ドメインに依らないところからドメイン特化の方向へ進むことに相当する。ソフトウェアにUIをつける大きな目的の一つは知識のある側(=大人)が知識のない側(=子供)に対して利便性を提供することだから、方向がそういう風になるのは当然である。

UIにはそうした知識のギャップを埋めるという目的のほかに、もう一つ(知識のある人がユーザだとしても)オペレーションのコストを低減するという目的もある。例えばプログラマでも、コマンドを組み合わせての開発環境よりも統合開発環境IDEツール)を使うと効率が上がることが多いが、そのIDEツールに搭載されている機能はコマンドを使う場合と同等でありオペレーションのコストが違うだけである。

この、UIの目的として「知識ギャップを埋める」と「オペレーションコスト低減」の2つがあることを明確に意識することはUIを考えるうえで非常に重要だ。この2つを分けないで設計を進めると、非常にチグハグなUIとなってしまうことが多い。そういう混同をしがちなのは理由があって、それはこの2つの目的が割と相反的だからだと思う。つまり「知識ギャップを埋める」目的で設計する場合想定ユーザは「知識のない人」なので「知識のない人でも使える」という視点になるが、「オペレーションコスト低減」の場合はオペレーションできることが前提のため想定ユーザは「知識のある人」であり「知識を持った人がいかに作業効率を上げられるか」という視点になるため、逆の視点がぶつかって混乱してしまいがちなのだ。ではその相反する目的を両立させる巧いやり方はないのだろうか?実はある。僕はソフトウェア開発の仕事をする中でこの方法を自分で考え出して、毎回UI設計のたびに適用している。ちょっと能書きを書いたが秘策と呼べるものではなく、とてもシンプルな方法だ。

「ウィザード」で入門して「車の運転くらいの難しさ」で免許皆伝へ

まず、相反する目的を一つのGUIに統一しないことが大切だ。2つの目的があるのだから、画面を分けるのだ。まずは「オペレーションコストの低減」という観点から入り、プロフェッショナル用途のGUIを設計してしまう。その際もアフォーダンスや視認性などのUIデザインにまつわる様々な知識は活用してよい。そうして出来上がるUIは「プロ用」であり、知識のない人には使いこなせないのだが、そこでGUIでよくある「ウィザード」を用意する。ウィザードを呼び出すだけで(あたかも幼児がママを呼ぶように)、あとはウィザードの側が必要なプロセスを踏んでくれるのでユーザはウィザードしたがって受け身で操作をすればよい。これで知識がなくてもとりあえずソフトウェアを使うことが出来る。ただしそれでもウィザードが用意されている機能しか使うことが出来ないため、そのソフトウェアのポテンシャルをイメージすることが出来ない。そこで、ウィザードは知識のない人でもそのソフトウェアの便益のメジャーなところを一通り享受できるようにいくつかのパターンを用意しておくと良い。

ある程度ソフトウェアの便益性の全体概要をつかめるようになったら、次はプロ用のインタフェースを使いこなすに至るまでのギャップをどう埋めるかを考えたUI設計だ。ここはかなりプロダクト依存の大きいところなのでケースバイケースだが、ここで一つ留意しておきたいのは「車の運転」についての話だ。車の運転というのは最初は誰もが上手に出来ないが、練習を重ねるうちに車が「身体の一部」のようになり最終的には殆どの人が必要十分なレベルで乗りこなせるようになる。それは、車の運転席のUIが人間の身体性にフィットし、車が手足のように身体化されやすいように設計されているからこそなせるワザだ。

よくあるUI設計上の誤解として、「知識のない人でも簡単に使えるように難しい機能を隠ぺいする」という方法が語られることがあるが、目指すべきは機能の隠ぺいによる簡易化ではなく「すべての機能をカバーしうるシンプルなUIで、最初は難しくても次第に身体化を促して簡単に感じられるようになるもの(*)」をデザインすることなのだ。なので僕は、これまで経験したソフトウェア開発プロジェクトで上司から「そんな難しいインタフェースじゃすぐにパッと使えないだろう」と言われるたびに毎回「いえ、車の運転くらいの難しさならむしろ習得して使いこなせるようになるものですよ」と反論してきた。もちろんその通りのUIとするには(*)が絵に描いた餅にならないよう工夫を重ねる必要はある。

では身体化を促すUI設計のノウハウとは何か?それはアリストテレスに始まる還元主義と、現代の複雑系に代表されるシステムダイナミクスについての考察が役に立つのだが、ちょっと長くなりすぎたので続きはまた日を改めて書きたいと思います。

長々と書きましたが、

最後まで読んでいただいて本当にありがとう。

それではまた明日。