目的指向プログラミング2010年08月14日 13時53分57秒

からリンクを辿って

を読み、ブクマで糞を投げてみたものの、年配の日本人プログラマーにおいては割とありがちな傾向なのではないかと思うところもあり、ちょっと書いてみようかしらとか思った次第。

オブジェクト指向にありがちな、それもとっても日本人的な誤解のひとつに、「オブジェクト = 物、物体」という解釈があると思う。確かに object という英単語には「物、物体」という意味があるのだけれど、実際には物体を表現しているわけではないオブジェクトについてまで、それを物体だと見立てて思考展開するんだ、と無理矢理自分を納得させながら Java や C# やその他のオブジェクト指向 (に対応した) プログラミング言語で頑張っている人って、実は若手でも少なくないんじゃないかと思う。

object という英単語には他にも「対象」や「目的、目標」などの意味がある。そのことを踏まえた上で、オブジェクト指向による設計について考えてみて欲しい。

例えば Window という名前のクラスがあるとする。このクラスの概要を説明する際、大抵の人は「ウィンドウを表すクラス」と書いてしまうのではないかと思う。これは多分、「オブジェクト = 物、物体」という前提をかなり意識した書き方だと思う。

あるいはポリモーフィズムを意識している人ならばもう少しマシに、「ウィンドウを表す基本クラス」などと書くかも知れない。そして派生クラスとして、FrameWindow があったり、 DialogBox があったり、はたまた見た目にも概念的にもウィンドウとは似ても似つかない FormControl なんてのがあったりするかも知れない。それでもこれらは「ウィンドウを表すオブジェクト」の一種をインスタンスとして生成するためのクラスとして扱われることになる。

まぁでもここまでは、それはそれでいいのかも知れない、とある程度納得できてしまうレベルの話なのかも知れない。フォーム部品もウィンドウの一種だと無理矢理納得することが、思考展開する上で圧倒的に不可能なことだとは思わない。でもそう思えるのは、これらは実行したときに、画面上で割と物体っぽく振る舞う概念だからなのではないか。

ちょっとしたゲームを作ろう、ということになって、その設計を考えたときに、そんなにたいそうなプログラムになるわけでもないし、ということで、実行時のシーンに応じてクラスを分けてみよう、と考えたとする。例えば以下の通りだ。

  • GameTitle
  • GamePlay
  • GameOver

名前を見ただけで、これらのクラスの「役割」は理解できると思う。GameTitle クラスはゲームのタイトルを表示する。プログラム実行時に最初に呼び出されるシーンだ。GamePlay クラスは実際にゲームを遊ぶプレイ中の制御処理を行う。タイトル表示シーンから特定のコントロール操作 (「start」ボタンを押す、等) により呼び出される。GameOver クラスはゲームオーバーになったときに行われる動作だ。スコアを表示したり、ハイスコアランキングに登録したり、といった処理が考えられる。

そもそもこのような設計手法は妥当なのか? 現実問題としてこのプログラムを実行時のシーンに応じてモジュール分けすると言うことは十分考えられることなので、少なくとも手段のひとつとして絶対にあり得ないと言うことはないだろう。個人的にはこれはこれで十分アリだと思うが、実際の開発においてはチームで議論するなり、リーダーが自身のセンスに基づいて主導するなりすればよいことだ。閑話休題。

さて、これらのクラスの概要を書くとしたら、あなたはどんな風に説明するか? 「ゲームタイトルを表すクラス」? 「ゲームプレイを表すクラス」? 「ゲームオーバーを表すクラス」? どれもクラス名以上のことは書いていない。そろそろ、「○○を表すクラス」論法は無理が生じてきていると言えるのではないだろうか?

それよりも、「本クラスにおいて、」と前置きして (あるいはそう前置きされている物と仮定して)、「ゲームタイトルのアニメーション表示を実装する」、「ゲームプレイ中の中枢的な制御を実装する。具体的には以下の制御が対象となる: …」、「ゲームオーバーの処理を実装する。ハイスコアランキングの登録を含む」などと説明した方が、すっきりするだろう。

オブジェクト指向の「オブジェクト」とは、観念的に「物」や「物体」を表すことを指す、と考えるより、設計においてプログラムを個別の部品というかモジュールに分ける際に、そのモジュールが何を「目的」として実装されるのか、そのモジュールが「目的」としている「対象」は何なのか、をはっきりさせるための、プログラミング上での表現手法、と考えるべきだ。

生成されるインスタンスを観念的に「物」と言い表すことはできるかも知れないが、オブジェクト指向プログラミングにおいて重要なファクターは、必ずしもそこだけではないはずだ。「クラスもインスタンスも両者を含めてオブジェクトと言います」なんて説明で日本人プログラマーをはぐらかすのはもう止めよう。オブジェクト指向とは、プログラムを「目的」単位でモジュール化する手法である。その単位こそが (文字通り) クラスであり、従ってクラスの説明は実装の目的を記述することであるべきだ。

そのことを念頭に置き、そうした観念に頭が慣れるまでは、「オブジェクト指向」という語は封印し、代わりに日本語で潔く、「目的指向」と言い表すようにした方がよいのではないか、と提案する次第なのである。

コメント

_ みながわけんじ ― 2010/08/20 08:59:09

OOの件については数ヶ月調べてみたが、OOプログラミングが得意な人は、クラスをオブジェクトと考えずにサブプログラム、つまりモジュールとして割り切って利用している。「モジュール指向」というのが直接的かもしれない。

コンストラクタで処理を実行し、メンバー変数に結果を格納して呼び出し元のクラスに返す、なんていう使い方が多いですね。

ただC#の場合はC言語のように、関数の引数にアドレス渡しなんてできるので、JAVAほどあえてクラスを使う理由がないですね。

最近以外だったのは、スクエニ社長の「我が社の公用語はC言語」です。ゲーム開発はオブジェクト指向言語が主流だと思ってたのですが、いまでもC言語で開発しているんですね。

_ T.MURACHI ― 2010/08/24 18:07:32

>みながわけんじ さま

コメントどもです。気づくのが遅くなって申し訳ない。

単純にモジュールであればよいのであれば、わざわざ OO を採用する必要はないのです。組み込み系やコンシューマゲーム系など、OO を採用することによるオーバーヘッドを無視できない領域は確かにあります。
スクエニにはスクエニの事情があるのですから、C を社内標準とすることに外野が異論を差し挟む余地はありません。が、仮に OO を採用している現場において、プログラマーたちが C でやってきたことと同じノリで「モジュール化されていれば十分」という姿勢で取り組んでいては、抽象化の手段として (即ち、メンテナンス性などのさまざまな作業効率化を目標として) OO の恩恵を享受するには至らないでしょう。

> コンストラクタで処理を実行し、メンバー変数に結果を格納して呼び出し元のクラスに返す、なんていう使い方が多いですね。

それ自体は悪いアプローチではないですが、それだけなら C の関数でもできることですよね? 複数のステータスを返す必要があるなら出力引数をたくさん並べるか、もしくは構造体を用いればいい。
でも、getter メソッドが動的に振る舞う (引数ではなく状態に応じて戻り値を変える) ようにしたい場合はどうでしょう? 状態の変化を知りたいときに、都度コンストラクタを呼んで、インスタンスを生成し直しますか? それよりは、プログラム起動時に生成したインスタンスをいちいち消さずに残しておいて、そいつの (動的に戻り値が変化する) メソッドを都度呼ぶように書いた方が、動作効率は高いでしょう。

みながわさんの記事や、上記コメントを見る限り、OO を採用する言語や現場においても、極力クラスを記述しないで済ませたいように見えます。個人的なスタンスとして、それを否定するつもりはありませんが、グループ開発で足並みをそろえること、その上で OO の利点を享受することを考慮されるならば、極端なクラス忌避はやめたほうがよろしいのではないかと思われます。
C# の場合、フリーソフトや oss の文化との接点が少ない為、 C# 言語自体の文化というのが見えにくいという面はありますが、どの言語でもその言語独自の文化というのは必ずあります。というか、「C#」でぐぐって先頭に来るサイトをいろいろと眺めてみるだけでも、その文化の一端は垣間見られるはずです (http://ufcpp.net/study/csharp/ ←おいらもここしばらく仕事で C# 使っているので割とお世話になってます…)。オブジェクト指向が云々言う以前にそういうものはどんどん参考にして取り入れていくべきです (まさに、習うより慣れろです)。技術的向上心を欠いてしまったら、それは技術者としての死を意味するのですから…。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
おいらがやっている会社の名前をひらがな4文字で。

コメント:

トラックバック

このエントリのトラックバックURL: http://harapeko.asablo.jp/blog/2010/08/14/5285989/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。