スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

プログラム+インターフェース=モジュール

アルゴリズム + データ構造 = プログラム
Algorithms + Data Structures = Programs
N.ヴィルト
最近しばらく関数やライブラリのインターフェースについての雑感を書いてきましたが、プログラムにおけるインターフェースの位置付けに関して面白い記事があったのでその紹介と感想を。

その記事と言うのは、Rogue Engineer's Diary/やさぐれ日記さんの「「アルゴリズム+データ構造=プログラム」? 本当に?」という記事。その内容は、前回の記事でも紹介したN.Wirth氏著の古典的名著のタイトルでもあり、プログラミングにおける格言とも言える「アルゴリズム+データ構造=プログラム」という考え方には、「インターフェース」の観点が抜けているんじゃないか、「アルゴリズム+データ構造+インターフェース=プログラム」とするべきじゃないか、といった内容。

なるほど。うまい表現です。でも、個人的には、もうちょっと表現を変えて次のような表現にした方がしっくりきます。
  • アルゴリズム+データ構造=プログラム
  • プログラム+インターフェース=モジュール
プログラムはルーチン、モジュールはライブラリとも言い換えられるかもしれません。つまり、個々の処理を行うプログラム(ルーチン)にインターフェースを与えてやることで、人間が理解しやすい、再利用性のあるモジュール(ライブラリ)になる、というイメージです。目的の処理を実行する「プログラム」を書くだけではなく、それを次回に再利用できる「モジュール」に仕上げるための、インターフェース設計。「+インターフェース」によって、コンピュータが処理する「プログラム」を、人間が利用する「モジュール」へ変化させる。

考え方をの単純な言葉で表現してみるというのは、考え方が整理されて気持ちがいいですね。

【関連記事】
似て非なるインターフェース
関数のユーザビリティ
選択できない選択肢

【関連リンク】
「アルゴリズム+データ構造=プログラム」? 本当に?(Rogue Engineer's Diary/やさぐれ日記)

【関連書籍】
オブジェクト指向における再利用のためのデザインパターン
Javaの格言―より良いオブジェクト設計のためのパターンと定石 Nigel Warren
Algorithms + Data Structures = Programs Niklaus Wirth
珠玉のプログラミング―本質を見抜いたアルゴリズムとデータ構造 - Jon Bentley
スポンサーサイト

似て非なるインターフェース

外見というものは一番ひどい偽りであるかもしれない。
シェークスピア
引き続き、プログラミングにおける関数(ライブラリ)インターフェースの話を。

今までに生み出されてきたプログラムの数は数知れず。さらにこうしている今も世の中では無数のソースコードが生み出されています。とはいえ、そのうちのほとんどはそれほど新規性のあるものではないでしょう。細かい違いはあれど、基本的なロジックは既にどこかで作られたものものを焼き直し、組み合わせているだけです。

アルゴリズム+データ構造=プログラム」と言えば、Pascalの設計者であるNiklauth Wirth氏によって書かれた古典的名著ですが、まさに言い得て妙。「アルゴリズム」と「データ構造」はまさにプログラムの基本構成要素であり、定石とも言えるパターンがあります。クイックソートや二分探索のアルゴリズムや、リスト構造や配列、ハッシュ等のデータ構造。それらの計算オーダー、メモリ効率。。。プログラミングのテキストには必ず出てきます。テキスト上で眺めている間は退屈なものですが、基本的なパターンを知っておくことは実際にプログラムを書く上では重要です。このようなテキストにあるような基本パターン以外にも、既存のソースコードからは、パターン化されたデータ構造やアルゴリズムを数多く見ることが出来ます。

さて、アルゴリズムやデータ構造に加えて、プログラミング、特にモジュール設計において重要なのがインターフェース設計。このインターフェースについても全てを一から考えるようなケースはほとんどなく、大抵の場合、リファレンスとなる前例があるでしょう。これも一種の定石のようなものです。

しかし、このインターフェースについては、アルゴリズムやデータ構造にはない注意点があります。それは、アルゴリズムやデータ構造がコンピュータを対象としたものであるのに対し、インターフェースはそれを使う人間を対象にしているという点です。使う対象の差は、変化に対する追従性に表れます。
アルゴリズムやデータ構造を変えたとしてもコンピュータならすぐ追従してくれます。しかし、例えば関数のインターフェースをちょっと変えても、それを使う人間はすぐに適応してはくれません。慣れ親しんだインターフェースであるほどそうです。人間の思い込みというものはそうすぐには変わりません。

ちょっと例を出しましょう。今、ファイルアクセスを行うライブラリの設計を行っているとします。POSIXのopen/close/read/writeは標準的なインターフェースと言えるので知っている人も多い。リファレンスとしては良いでしょう。 でもここで一つ問題が。このopenのflagsには、ファイルが存在しないときは作成するというO_CREATというフラグがあります。O_CREATEではなくO_CREATです。E一文字くらい省略するなよと何人の人が思ったことでしょう。ということで今回はO_CREATはO_CREATEと変えたとします。
さて、ここで何が起こるでしょうか。大抵のユーザはI/Fを一瞥して、「あぁ、POSIXと同じだな」と思い込んで、詳細な仕様をわざわざ見ずに使うでしょう。となると、ファイルを作成したいときは思わずO_CREATと指定してしまいます。この場合は、コンパイルでエラーになるだけなので対した被害はありませんが、実行時でしか気がつかないような機能的な違いだと非常にやっかいです。
これがPOSIXのopen()と似ても似つかないインターフェースならユーザーはCREATEと指定してくれる可能性が高いでしょう。「似て非なる」という点が混乱のもとになっているのです。

アルゴリズムやデータ構造といったコンピュータを相手にする部分は、小さな工夫を積み重ねることで効果は上がるでしょう。しかしインターフェースのような人間が使うものは小さな変化を積み重ねていては、かえって混乱を招くだけです。「似て非なる」はコンピュータには別々できても人間には分かり難いものです。キーボードのQWERTY配列は人間工学的に見て優れているとは言えませんが、そうは分かっていてもなかなか変更されないのも良く似た理由と考えられるでしょう。

一から新たなインターフェースを設計する際には、単純に最も良いと思われるものを目指せば良いでしょう。しかし、それが何かしら基になるものを改善するようなものである場合は、改善後のインターフェースに対する利便性等だけでなく、変化に対する移行性、時には互換性といったものに対する配慮も必要でしょう。

【関連記事】
関数のユーザビリティ
選択できない選択肢

【関連リンク】
入力法および表記法のヒューマン・インタフェース学入門(QWERTY成立の解説等)

【関連書籍】
Algorithms + Data Structures = Programs Niklaus Wirth
アルゴリズムとデータ構造 - N.Wirth
珠玉のプログラミング―本質を見抜いたアルゴリズムとデータ構造 - Jon Bentley
プログラミング作法 - Brian Kernighan

選択できない選択肢

あなたの実力以上に有徳であろうとするな。
できそうもないことを己に要求するな。
プログラミングにおいて最も重要なもののひとつ。「美しさ」。 「美しい」ソースコードと「読みやすい」ソースコードとは必ずしも一致するのものではありませんが、美しいソースコードは可読性や拡張性が高く、保守性にも優れています。美しいコードを書こうという努力は、決して自己満足に終わるものではありません。

さて、「美しい」といってしまうとあまりにも漠然としているのですが、今回とりあげるのはその中の「統一性」です。
インターフェース設計においては、複数の機能をひとつのインターフェースで実現しようとすることがあります。しかし、もともと複数の機能ですから、機能によって必要とするパラメータが微妙に異なったり、操作対象によって使えたり使えなかたったりする場合がでてくることがあります。
よく言われるオブジェクト指向のアンチパターンにfat interfaceと呼ばれるものがあります。一部の子クラスでのみ有効な機能も全てスーパークラスのインターフェースに詰め込んでしまい、スーパークラスのインターフェースが膨れ上がる。おまけに、実オブジェクトのクラスによって使えるインターフェースと使えないインターフェースまで出てきてしまう。fat interfaceの名の通り、インターフェースの数が膨大になるもの勿論問題なのですが、それ以上に、使えるか使えないか一見して分からないというのは、使う側にとっては非常に問題です。
他の例としては、いろんな機能要求に答えるために、複数の引数を持ったり、フラグ型引数を持つもの。例としては、POSIXのopen()関数。この関数では、flagsにはこれとこれが同時指定可能とか、このflagsにはこのフラグとこのフラグは同時指定可能とか、modeはflagsがこの値のときだけ有効とか、関数の形や型定義からは判断できない仕様ができてきしまっています。

誤解のないように書いておくと、ひとつの関数やインターフェースに複数の機能をバインドしてしまうのはいけないことだと言っているわけではありません。インターフェースの統一は非常に重要な観点です。上記の例で問題なのでは、インターフェース中に「選択できない選択肢」があることです。仕様を確認すれば分かるというのはなしです。そもそも、選べないものは見せるべきではありません。

インターフェースを統一・共通化しようとした際に、上記のような「選択できない選択肢」が登場しそうな場合には、本当に共通化するべきか再考するべきです。そもそも共通項のない機能であれば無理して共通化する必要はありません。共通項が多い場合や、相乗効果が得られそうな場合には統一する 価値があるかもしれません。先のopen関数の場合、多少不要な引数が現れることもありますが、readとwriteのオープン処理が共通化されているために、read/writeモードでファイルをオープンするといったこともできていますので、それほど悪い例とは思いません。

本当に「美しい」コードは、見た目のエレガントさだけではなく、機能性・理解性も優れているものです。

【関連記事】
関数のユーザビリティ

【関連書籍】
アンチパターン―ソフトウェア危篤患者の救出
J2EEアンチパターン
サーバーサイドJavaアンチパターン
Code Complete第2版―完全なプログラミングを目指して

関数のユーザビリティ

しかし,単純なものでも説明がいるような道具があるとするなら,これは,よいインターフェイスを持った道具ではないのだ。
J・J・ギブソン 『アフォーダンス理論』
改めて述べるまでもなく、IT関連技術の発展は目覚しいものがあります。PCを例にとれば、処理速度や容量・解像度のような定量的な尺度で計れる性能については、大抵のユーザーの需要はすでに満たしているのではないでしょうか。このような性能面での機能が満たされれば、次にユーザーが求めるのは「機能性」、そして「使い勝手」です。
最近はこの「使い勝手」を決定付けるものとして、ユーザーインターフェース(User Interfase:UI)に関する議論が活発になっています。GUIを始めとするUI設計に関する記事や書籍もよく目にしますし、日用品や家電製品でもユニバーサルデザインを前面に押し出した製品をよく見かけるようにもなってきました。

ところでこのUIに関する議論は、プログラミングにおける関数やクラスの設計も同じことです。関数やクラスが含まれるライブラリの使用者によっては、インターフェースのみが重要であって、実装には興味がないのです。ここでいうインターフェースとは、ヘッダファイルに直接現れるような関数やクラスの宣言のみではなく、処理内容の外部仕様も含みます。

一般的にUIというと機械と人間を媒介するものを指すので、関数やクラスのインターフェースはUIとは少し違うように思えるかもしれません。しかし、実際にそのライブラリを使うのが別のあるプログラムであるとしても、それを使わせようとプログラミングするのはプログラマたる人間です。そういう観点で考えれば、ライブラリ設計にもUI設計の考え方が当てはまるのではないでしょうか。

例えば、最近よく耳にする「アフォーダンス(affordance)」。物体の持つ属性(形、色、材質、etc.)が、物体自身をどう取り扱ったら良いかについてのメッセージをユーザに対して発している、とする考え方です。Webアプリケーションであれば、リンクをボタンの形にすることで、これは押すものだとユーザーに訴える。
プログラミングの例にあてはめると、関数の名前や引数を見ただけで、その仕様がわかるようにする。例えば、is_A()という名前の関数名のようにis_xxx()という名前によって、関数がbool値を返すということがわかるといった感じです。

その他、昨今のUIの議論からプログラミングの設計について考えさせられるところは多いです。詳しく書き出すと長くなりそうなので、改めて追々書いていきたいと思います。

【関連記事】
変数の命名規則

【関連書籍】
誰のためのデザイン?―認知科学者のデザイン原論
インターフェイスの街角―本当に使いやすいユーザー・インターフェイスの極意
アフォーダンス-新しい認知の理論

本のおすすめ

4873115655

4274065979

4822236862

4274068579

4822255131

B00SIM19YS


プロフィール

  • Author:proger
  • 組み込み関係で仕事してます

ブログ内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。