先輩教えて!プログラミングのabc(オブジェクト指向編)---オブジェクトって,やさしいの?(上)
「ねぇ。先輩」
「うん?」
「先輩は,オブジェクト指向をすぐマスターできたんですか」
「そうだなぁ。結構,時間がかかったと思うよ」
「(ふうっとため息をついて)やっぱり,時間がかかりますよね」
「どうしたの。オレみたいに構造化パラダイムからの乗り換えじゃないから,それほど苦労しないよ」
「でも,ちょっと納得できないところがあるんですよね」
オブジェクト指向が難しい理由の一つとしてよくいわれるのが,構造化プログラミングとの考え方の違いである。この連載では既に触れているが,もう一度構造化プログラミングとオブジェクト指向プログラミングの根本的な考え方を示しておこう。
図1●プログラムの流れの例 ここでは「制御コードを埋め込んだファイルを印刷する」といった処理を考えた。ファイルから1文字ずつ読み出し,エスケープ(ESC)コードが来たらコマンドと判断して印刷する状態(太字,細字,網掛けなど)を変える。これをファイルの終端に到達するまで繰り返す。最終的にプログラミング作業は,こういった処理手順を考えることに行き着く。 |
どちらも根元的には,プログラムを単純な構造に分解して,その単位ごとに役割を明確化して完成度を高める狙いがある。構造化プログラミングの場合,プログラムの「流れ」を構造として分割する。つまり分割の単位が構造化制御構文であったり,独立性の高いサブルーチンであったりする。一方オブジェクト指向プログラミングの場合,データを中心に分割する。データとそれに対する操作をひとまとめにしたものがオブジェクトであり,その単位でシステムを分割する。この分割の単位の違いが,両者の大きな違いとなっている。
元々プログラムには「流れ」がある
だが構造化プログラミングに比べ,オブジェクト指向プログラミングはハードルが高い。必ずどこかで考え方を切り替えなければならないからだ注1)。
ここで「プログラミング」という行為そのものについて考えてみよう。プログラムとは元々,コンピュータに何かの処理をさせるための手順を記録したものである。機械語のレベルまで落ちてしまえばある意味,明らかだろう。そこには単純な命令が順番に並んでいる。この順番が手順を表現している。手順とはすなわち,プログラムの「流れ」である(図1[拡大表示])。したがって流れを単純な構造に分割していくというアイデアは,非常に自然な発想だと言える。おそらく,オブジェクト指向プログラミングから学んだ人であっても,なんら意識することなくこのアイデアを活用していることは想像に難くない。
逆に言えば,オブジェクトを定義するという行為自体がプログラミングにおいては自然ではないのかもしれない。だから難しいとも言える。コンピュータ・システムを大局から分析するときには,「このデータをどう扱うか」を考えるのは自然である。しかし,実際にプログラミングする時点では,「この処理をどのような手順で実現するか」を考えるのもまた自然なのだ。ここに大きなギャップがある。つまり,分析や整理にオブジェクトの考え方は重要だが,最終的なステップで構造化的な考え方をしなければならないのだ(図2[拡大表示])。
図2●オブジェクト指向的側面と手続き的側面 分析/設計段階では,データを中心とした着目は有効である。だがそれを実装する段階にはいると,手続き的な側面を考慮しなければならない。オブジェクト指向に基づく開発をしていると,オブジェクト的な視点と,手続き的な視点の両方が必要となる。 |
考え方の切り替えが必ず存在する
このことが,元々構造化プログラミングに慣れ親しんできた人にとって問題を難しくしている。オブジェクト指向に沿って考えるためには,発想を転換しなければならない。しかしその後,また慣れ親しんだ手順ベースの考え方に引き戻される。だからオブジェクト指向の考え方を徹底できず,「オブジェクト指向言語で記述した構造化されたプログラム」になりがちなのである。アタマを切り替えられないから起こることだ。
考え方の切り替えという点ではもう一つ,指摘しておきたいことがある。オブジェクトとクラスの関係である。データに着目して整理していくとき,データそのものを意識しているはずである。しかし実装するのはクラスである。UML(Unified Modeling Language)などを使ってシステムを分析するときも,定義するのはクラスである。つまり,データそのものではなく,データを入れる器に基づいて整理していくことになる。実装する場合やシステム設計する場合はこれではなく,クラスに着目する。だからユースケースなどを基にオブジェクトを抽出したら,今度はその入れ物となるクラスを定義するのである。例えば伝票のような,入れ物と実体が物理的に存在する(記入前の伝票と,記入済みの伝票)場合には明確である。しかし現実には,これほどきれいなクラス-インスタンスの関係はあまりない。目前にある“もの”は実体であって,クラスを定義するにはこれを抽象化しなければならない。ここにも一種の発想の転換が必要となる。