プログラミング言語にはいろいろなものがあります。いくつかのジャンルに分けられるのですが、Javaはオブジェクト指向プログラミング言語(Object Oriented Programming Language:OOPLと略す)の1つです。では、オブジェクト指向とは一体何でしょうか?一言でいうと「アプリケーションを部品の集まりとしてとらえる」という方法です。まずそれについて見てみましょう。
ソフトウェア危機とソフトウェア工学
以前と比べて、ハードウェアの性能は飛躍的に向上してきました。以前はコンピュータのリソース(正しくは「資源」という意味ですが、性能と考えればわかりやすいでしょう)が小さく限られていたので、ソフトウェア開発者はできるだけ無駄な処理を行わないようにしたり機能を削ったりしなければなりませんでした。それに対して現在では、ハードウェアが高性能な処理を行うことができるので、ソフトウェアも大規模かつ複雑な処理を行うことができるようになったのです。良いことばかりのようですが、考え方を変えると大規模で複雑なソフトウェアを作らなければいけないのです。複雑なシステムを作り上げることは困難で、時間がかかり、失敗することもあります。失敗を取り戻すために人を増やそうとしても、高い技術や知識を持つ人はなかなか見つかりません。教育するにも、昔とは違って新しく学ばなければいけないことがたくさんあります。実際に起こりうる問題としては開発スケジュールの遅延や低品質化、そしてコストの増大などが考えられます。こういった状況を“ソフトウェア危機”と呼びます。(ソフトウェア危機という呼び方は1968年に開かれた国際会議で名づけられました。)
ソフトウェア危機を引き起こす諸問題を解決するために“ソフトウェア工学”が必要であるということが、前述の国際会議で新しく言われるようになりました。ソフトウェア工学を簡単に言うと、ソフトウェアを開発したり利用したりするための様々な理論と具体的な方法です。その1つとしてオブジェクト指向があるわけです。
大規模なソフトウェアを一度に作るのは大変です。そのため、実際の開発ではまず「分割して少しずつ作ろう」ということになるでしょう。これはオブジェクト指向でなくとも行われてきたことです。問題はその分割の基準の決め方にあります。
一般的なプログラムの構成
ソフトウェアを作るためのプログラムは使用するデータと、そのデータを処理する機能から成り立ちます。以前はそのうち機能の違いについて注目し、機能ごとで分割したやり方が主でした。処理ごとに分割して作成した部品(プログラム)をモジュールと言います。このプログラムの考え方・書き方を手続き型と呼び、大規模なシステム開発ではこれを段階的に行う構造化設計手法という方法が採用されていました。
しかし、このやり方は機能とデータの関連性・利用方法は考慮されていません。様々な処理が別々のモジュールとして存在していますが、それぞれのモジュールが同じデータを利用している、などということはもちろん考えられます。すると、例えば開発途中にデータの構成を変えると困ったことが発生します。そのデータを利用・操作している機能(つまり部品)すべてを修正しなければならなくなるのです。
この図ではデータにアクセスしている部品Aと部品Bを修正しなければいけません。部品Cのように無関係の部分もありますが、無関係かどうかは調べてみないとわかりません。これは大規模なシステムでは大きな労力になります。修正すべき点を見過ごしてしまうこともあり、バグの増大にもつながります。
これに対してデータ中心に分割を行う“DOA”(Data Oriented Approach)という方法もあり、その名の通りデータ構造をまず先にはっきりさせます。場合によってはこちらの方法を用いることもありますが、こちらだけではやはり不十分です。結局、データと機能を別物として考えると良くない、と考えられるようになりました。
オブジェクト指向の場合
オブジェクト指向では、データと機能は分離しません。とはいってもプログラム自体は分割していきます。いったいどのようにするのでしょうか。次の図がそのイメージですが、いくつかに分割した部品それぞれがデータと機能を持っています。そして、それぞれの部品を“オブジェクト”と呼びます。一言で言ってしまうならば「関係のないものは別の部品に分割し、関係のあるものはまとめておく」ということになります。例えば人間というオブジェクトを使うなら、「人間に関するデータ」と「人間に関する機能」のみを「人間オブジェクト」の中に入れます。机とか商品の在庫とかウィンドウとか、人間に関係ないものはそれぞれのオブジェクトを別に作ります。
それぞれのオブジェクトは自分の仕事のみをし、自分のデータのみを参照します。他のオブジェクト内のデータは直接参照しません。「参照するための機能」という少々回りくどいものを作って間接的にアクセスします。これは考え方によれば効率の悪いプログラムです。余計な機能を作らなければいけませんし、そこを呼び出す分、処理が遅くなります。