オブジェクト指向 (object-oriented) という考え方は、古い歴史をもっている。 1960 年代の後半に Simula67 というシミュレーション言語の中にオブジェクト、クラス、継承というオブジェクト指向における重要な概念が登場したことが起源だといわれている。 1980 年代には Smalltalk というオブジェクト指向言語のプロモーション活動と相まって、ソフトウェア開発に関する問題解決のキャッチフレーズになった。
この章では、SSS の後継製品である RRR (トリプルアール) ファミリーの開発を始める前の 1994 年にウッドランド社とアプリテック社が共同で行った“部品化再利用システムの検討の過程”を振り返り、 オブジェクト指向をどう捉らえたのかをできるだけ率直にご報告する。
ウッドランド社の SSS (トリプルエス) は、 データ中心 (data-oriented) アプローチという考え方のよい点を取り入れたが、 オブジェクト指向という考え方とは独立に開発された。 しかし、SSS は Smalltalk というオブジェクト指向システムにおけるソフトウェア開発とよく似たところをもっていた。
Smalltalk システムは、単なるオブジェクト指向プログラミング言語だと捉らえるよりも、 階層をなすオブジェクト群 (部品といえそうなもの) を内に抱えた部品化再利用システムだと見る方が当たっている。
実際、そこに含まれるオブジェクト群とそれらがどう構成されているのかを理解した達人は、ビジュアルなある種のアプリケーションプログラムをたちどころに開発できるようになる。
Smalltalk システムにおけるソフトウェア開発とは、一部のオブジェクトを変更することなりといわれる。 これはオブジェクトを再利用する実態を的確に表現した言い方である。 オブジェクトの宣言部やプロシージャ部分を変更するか、または変更したオブジェクトを新規オブジェクトとして登録することが開発のすべてなのだ。 いわば、広義のプログラムカスタマイズが大変にしやすいシステムなのである。 Smalltalk システムのオブジェクト構成はよく考えて設計されているので、それを理解した達人は、ビジュアルなある種のアプリケーションプログラムを作るときに、どこを変更すればよいのか分かるようになる。 そして、オブジェクトの一部を追加・変更・削除するだけで、Smalltalk システムを思いどおりのシステムに“変身”させることができるということなのだ。
一方 SSS は、ビジネス分野の販売管理業務の特注対応業務パッケージである。 SSS の中には、部品セットとその合成ツールとが含まれていて、これら二つによって部品化再利用システムを構成している。 SSS によって開発された (つまりカスタマイズの結果として作られた) 業務プログラムは既に 5000 以上の出荷実績があった (当時の値)。
SSS の特長はカスタマイズを容易にするための新たな工夫にある。 それは前述のデータ項目部品という形の約 2000 個の SSS 部品セットとその合成ツールに凝縮されている。
SSS ツールによるカスタマイズの基本は、データ項目部品を選ぶことである。 選ぶといっても 2000 個の部品の一つ一つを指定するということではない。 あらかじめ部品セットの中から標準の部品群が選ばれていて、実際に動作する業務プログラムになっているので、標準の部品群の中の顧客要件に合わないいくつかの部品を適切なデータ項目部品に置き換えるだけでよいのである。 これがカスタマイズの中心作業である。
SSS 部品セットを構成するデータ項目部品の特徴は、それぞれ一つのデータ項目に対応づけられている点だ。 ビジネス分野ではデータ項目名によって仕様変更要求が表現されるという性質があるので、2000 個の中から目指すデータ項目部品を簡単に見つけ出すことができる。 なぜなら、各データ項目部品には対応するデータ項目名で始まる名前を付けることにしたからである。 なお、「付録2.ビジネス分野の業務プログラムの一般的な特徴」 も合わせてご参照いただきたい。
こうした命名がなされているために、何か変更が必要になった場合に、どのデータ項目部品を置き換えるべきか、または削除すべきかがデータ項目名によって自ずと分かってしまう。 また、どのデータ項目部品に置き換えるべきか、または追加すべきかに関しても、データ項目名で分類された数個の候補の中から一つを選べばよい形になる。 このように適切な部品を選択するだけで、ほぼ思いどおりの販売管理システムが合成できる。
よりぴったりとした業務プログラムにカスタマイズするには、データ項目部品の内部を変更したり、新規開発したりすることも必要になる。 つまり、広義のプログラムカスタマイズを行うのである。 こうした作業の中で、データ項目部品を新規に開発する場合は、部品倉庫から類似したものを取り出してきて部分的に変更して新たに登録することが普通である。 この種のカスタマイズ作業においても当然ながら再利用を基本にしている。
要するに、一部の部品の変更作業や新たな部品の登録作業などは、Smalltalk システムにおけるプログラムカスタマイズ作業と非常によく似ている。 なお、この種のカスタマイズを特別に部品カスタマイズと名づけたことは 「1.3 特注対応業務パッケージ」 で述べたとおりである。
部品化したソフトウェアの再利用の局面をみると、Smalltalk システムにおいても SSS においても部品カスタマイズを実施しているとみなすことができ、その作業方法はほとんど同じである。 いや、SSS の方は、その適用分野をビジネス分野に限定している分だけ、そこに特化した工夫があることに注目すべきだろう。
第一に: SSS ツールにおける工夫は、‘ビジネスロジック部品’の変更作業をより簡単にするために、あらかじめ用意したいくつかの候補の中から選べるようにした点である。 もちろん Smalltalk システムのオブジェクトに対しても、同様の選択機構を設けるのはたやすいことである。 しかし、その適用分野を限定しないと、どのようなオブジェクトを候補にすればよいのか的を絞れない。 候補の中から選択できるようにするには、オブジェクトや‘ビジネスロジック部品’の候補の品揃えの方が重要なのである。 選択機構の方は、誰もが思い付くようなちょっとした工夫に過ぎないので、Smalltalk システムにもあって良さそうなものであり、この機構を作るだけでよければ簡単にできることである。 これに対して、候補の品揃えの方は、どんなカスタマイズが実際にあり得るのかという経験や知識や洞察力がないとできないことである。
第二に: SSS 部品セットにおける工夫は、データ項目に対応づけた‘ビジネスロジック部品’をその主要構成要素にしたために、変更すべき部品を特定する作業が極めて簡単になった点である。 Smalltalk システムでは、どのオブジェクトを変更すべきなのかを特定するのが簡単ではない。 オブジェクトを特定するには、そこに含まれている階層をなすオブジェクト群の構成とそれぞれの内容を理解した達人になることが必要なので、「SSS のように非熟練者にも簡単にできる」 ようにはならない。
SSS においては、ビジネス分野では有効性が認められたデータ中心アプローチというショック療法的な考え方のよい点を取り入れて、‘ビジネスロジック部品’をデータ項目に対応づけた。 この結果、変更すべき‘ビジネスロジック部品’を特定する作業が容易になった。 なお、こうした経緯から想像できるように、この“データ項目に対応づける”という方法はビジネス分野以外にもうまく働く保証はないが、少なくともこの分野では有効に働いている。
一般的な傾向として、Smalltalk システムやオブジェクト指向なるものは、超汎用的な原理・原則を重視するためか、特定の分野に焦点を絞った個々の改善に目が届かないように感じられる。 SSS はそういった分野の一つを掘り下げたのだといえる。
Smalltalk の適用分野とはどのような分野なのかを探ってみよう。
Smalltalk をオブジェクト指向の単なるプログラミング言語として眺めてみると、特定の分野を対象にしたものではなく、汎用的なものだということが分かる。
そして、Smalltalk とは、階層をなすオブジェクト群を含んだオブジェクト指向システムだとみると、“MVC (model view controller) の三つに分割するのだ”という分割指針のもとに整然と体系化された構成をしており、 その構成方法とそれに従ったオブジェクト群とによって適用分野が色づけされている。 何の分野と呼んでよいのか表現しにくいのであるが、ビジュアルなある種のアプリケーションプログラムがたちどころに開発できるのである。
ところで、現状の Smalltalk システムでは、ビジネス分野の業務プログラムが簡単に開発できるわけではない。 そこで、もしも Smalltalk というオブジェクト指向プログラミング言語の中にビジネス分野向けのオブジェクト群を含めたら、 どうでなるだろうか? たとえば、生産管理業務向け Smalltalk システムとか、 SSS のように販売管理業務向け Smalltalk システムにしてみるのである。 ひょっとすると、ビジネス分野向けの Smalltalk システムに生まれ変わるかもしれない。 機会があれば、このような試みをしてみたいものである。
この節では、SSS の後継製品 RRR ファミリーの開発を始める前の検討の過程を振り返りながら、一つの開発現場でオブジェクト指向をどのように噛み砕いて理解していったのかを報告する。
SSS は Smalltalk システムと似たところもつ“部品化再利用システム”だったので、 この特長を生かし、かつ SSS よりも洗練されたシステムを目指して RRR ファミリーの検討をおこなった。 その中では、オブジェクト指向という考え方を強く“意識”した。 多くの人々に受け入れられるためには、できるだけ一般に流布している考え方やツールに沿うべきだという方針を取ったのである。 ただし、ビジネス分野をターゲットにした SSS の成果のうちで、どこにもお手本が見つからなかったものは大事に育てようとしたことは、いうまでもない。
この“部品化再利用システム”をリファインするための検討の大半は、個別の製品化よりも、ものの本質を捉らえることの方が重要であるという考え方に従って行った。 したがって、RRR ファミリーという製品のための検討だけではなく、実用的で効果的な“部品化再利用システム”はどうあるべきかを解き明かすための検討になった。 そこでは、目指すシステムを部品化アプリ再利用システムと名づけて検討したのである。
以下には、「RRR ファミリー」 という製品名と、「部品化アプリ再利用システム」 という一般名称が出現する。 要するに、部品化アプリ再利用システムを開発して製品とした一つの例が RRR ファミリーだと考えていただきたい。
また、以下ではオブジェクト指向やその周辺技術に関する一般的な説明にかなりのページを割いてしまったが、こうしたことの説明に本意があるのではない。 この章は、部品化アプリ再利用システムの検討を通して、オブジェクト指向をどう捉らえたのかの報告であることを、繰り返しになるが強調しておく。
オブジェクト指向という考え方を適用するにあたって、まず最初に問題になったのは、何をオブジェクトに対応づけるかという点である。 オブジェクト指向なるものは、ある枠組みを備えていて、「ソフトウェアをその枠組みに従ったモデルに沿うようにすると恩恵がある」 といって勧める思想のようなものであるといえる。 そこでは、何をオブジェクトに対応づけるのかは基本的に自由である。 だからといって、勝手に決めてよいわけではない。 オブジェクトとしてふさわしくないものを対応させると、オブジェクト指向の恩恵にあずかることができない。 このためにオブジェクト指向の設計法や分析法が重要だといわれている。
部品化アプリ再利用システムのフレームワークの検討では、何をオブジェクトに対応づけるかについて二つの候補があった。
一つは SSS で重要な役割を果たしたデータ項目であり、もう一つは構造化分析法においてエンティティと呼ばれているものである。
データ項目とは、ビジネス分野の具体例を挙げると“顧客コード”とか、“受注日付”とか、“商品単価”のような要素的なデータのことである。 ビジネス分野の業務プログラムが取り扱うデータ項目は、数百から数万に及ぶことが普通である。 ちなみに、SSS 部品セットとしては千を越えるデータ項目に対応した細切れのプログラム群になっていることは前述したとおりである。
データ項目の数は多いのであるが、ビジネス分野の業務用語とデータ項目名の間には明確な対応関係がある。 そして、業務内容の変更は、業務用語またはデータ項目名を使って表現されるのが普通である。 したがって、データ項目という単位は、データ中心アプローチにおいても指摘されているように、ビジネス分野では重要な意味をもつ単位なのである。
エンティティ (entity) とは、構造化分析法や構造化設計法で使われている言葉である。 一般の辞書には、実在物、実体、本体などの訳語が載っている。 構造化分析法では、関心をもつべきモノ (その状況を把握したり管理したりコントロールしたりしたいモノ) を取りあげて、 それらのモノの間にどのような関係があるのかを分析するそして、エンティティ・リレーションシップ・モデルという形にモデル化して、 そのモデルを ER ダイアグラム (ERD) として描いたりするものだが、そこに登場するのがエンティティである。 ビジネス分野を対象にしたエンティティの具体例を挙げると“顧客”とか、“受注”とか、“商品”とかといったモノのことである。
トピック 2: 構造化とは
ソフトウェア開発の方法についての書き物の中には“構造化〜”という形の修飾語がしばしば使われる。 ダイクストラ (Dijkstra,E.W.) によって提唱された構造化プログラミングが 1970 年代に評判になってから、 この“構造化”という用語はソフトウェア開発に関する問題解決のキャッチフレーズとして盛んに使われるようになった。 なお、その後、この種のキャッチフレーズとしての地位は、古い起源をもつ“オブジェクト指向”という修飾語に受け継がれている。
まず手始めに、構造化プログラミングに関して理解するために、そのエッセンスを含んだ以下の楽譜の記号に従って説明文を繰り返し読んでいただきたい。 なお、以下を読む前に、プログラミングに関する知識を仕入れるには、「付録1.プログラムの実行とは」 を一読することをお勧めする。
構造化プログラミングを学習すると、while 文のような条件付きループ構造などのいくつかのパターンを用いることによって非構造的な go to 文を駆逐できるという定理にであう。 これは数学的な証明がなされているので定理と呼ぶのがふさわしい。 この後で、スパゲッティ状態のプログラムコードを作らないためには、 go to 文ではなく while 文や case 文などの厳選された制御構造 (プログラムの流れをコントロールするための文の書き方) を用いることが重要だということをたたきこまれる。
実際に、構造化プログラミングは大いに効果があった。 プログラムの制御構造を見やすいパターンに標準化するという点において功績があったのである。
悪玉の go to 文は、いわば第何章の何節の何項に飛んでいってそこを読めと命じる文なので、こんな文が随所に出現したならば、文章全体が見にくくなるのは当然のことである。 善玉の一つの while 文は、たとえば 「月末になるまで毎日以下の計算を繰り返せ」 と命じる文であり、 どのような条件の場合に繰り返すのか、また何を繰り返せばよいのか、これらを明確にした上で繰り返しを命じる制御構造である。 この説明文の先頭にある“繰り返して演奏することを命じる楽譜の記号”と同様に、while 文は見やすい制御構造なのである。 そして、善玉のもう一つの case 文は箇条書きのような制御構造なので、これを使えばプログラムが見やすくなるのは明らかである。 このように、構造化プログラミングはプログラムの“見やすさ”を高める効果があったのである。
ただし、善玉に含まれるサブルーチン化という制御構造は大抵の場合、効果的なのだが、どんな場合でも見やすくなるとは限らないという意見もある。 サブルーチン化は、いわば意味がぎっしりと詰まった言葉を定義して、そういう言葉を使うことに相当する。 したがって、その言葉の意味をしっかりと捉らえることが必要になり、これをやりすぎることに抵抗があるのだろう。 要するに、サブルーチン化は単なる見やすさだけではかたづかない意味論の世界に入り込むので、分かりやすい意味の付け方や、意味の詰まった言葉を使いこなす力が問題になるということである。
なお、本書では“見やすさ”と“読みやすさ”とを区別しており、“読みやすさ”については後述する。
構造化プログラミングは有効であったが、もちろんそれだけでソフトウェア開発に関するすべての問題が解決することにはならない。 まだまだ問題が山積していることが分かってきた。 こうなると、一般に前工程の責任が重要だとしたがるもので、1970 年代の半ばからプログラミングに先立って行う概要設計を構造化すべきだとして構造化設計法が提唱されたり、 さらに構造化分析法を掲げてそれ以前の分析作業を見直すことが重要だと叫ばれたりした。 分析や概要設計の見直しは確かに重要であるが、どうすれば分析や概要設計をうまく構造化できるのか、誰もがわかるようには解き明かしてくれなかった。 したがって、その叫びに続いての高らかな勝ちどきの宣言はなかったように記憶している。
“オブジェクト指向”という修飾語が台頭してきたのは、そのような時期であった。
部品化アプリ再利用システムの検討を開始したときには、エンティティ (entity) をオブジェクトに対応づける方が、現実世界を素直にモデル化しようとするオブジェクト指向の考え方に、より近いと考えた。 ちなみに、オブジェクト指向なるものの意味するところは、目的指向ではなく、対象物指向またはモノ指向という方が当たっているし、さらに噛み砕いて言うと、ソフトウェアの構成を設計する際に現実世界のモノとの対応関係を重視しようということである。
エンティティをオブジェクトに対応づけると、構造化分析法や構造化設計法からの連続性もある。 また、エンティティは、リレーショナルデータベース (RDB) の理論における知る人ぞ知る正規化したテーブルに近いものだといってもよいだろう。 これらの理由から、エンティティをオブジェクトに対応づけるのが無難だと思われた。
エンティティをオブジェクトに対応づけると、構造化分析法や構造化設計法においてエンティティの属性 (アトリビュート) と呼んでいたものは、 オブジェクト指向におけるインスタンス変数 (C++ というオブジェクト指向プログラミング言語ではプライベートメンバ変数と呼ばれている) に相当することになる。 これは、正規化したテーブルのカラムとか項目と呼ばれるものにも相当するし、データ中心アプローチや SSS で重要な役割を果たしているデータ項目にも相当するものである。
具体的に言うと、たとえば“商品”をオブジェクトとみなすと“商品名称”とか、“商品単価”とか、“商品サイズ”とかという商品オブジェクトの属性を表すデータ項目がインスタンス変数 (またはプライベートメンバ変数) になる。
いろいろな用語が氾濫してしまった。 このように、同じ内容でもその出身母体の違いによって異なる用語 (異名同義語) が用いられているのは困ったことである。 不慣れな言葉が出現したときには、慣れた言葉を頼りにして理解するのがよいだろう。 それぞれの用語は、強調する点やニュアンスや抽象化のレベルなどに多少の違いがある。 しかし、その用語が表す実体がほぼ同じであれば、同じものだと考えていただきたい。 以下にこういった用語の対応関係を示す。
オブジェクト指向の用語: オブジェクト指向以外の用語:
オブジェクト <===> エンティティ
≒ テーブル
≒ ファイルのレコード形式
インスタンス変数 <===> 属性 (アトリビュート)
≒ 属性 (アトリビュート)
≒ プライベートメンバ変数
≒ カラム または フィールド
≒ データ項目 または 項目
エンティティをオブジェクトに対応づけることは、ある意味では構造化分析法や構造化設計法の成果を踏襲することなので、進歩がないと思われるかもしれないが、そうとも言い切れない。
初期の構造化プログラミングにおいては、プロシージャ部分の構造化を最大の関心事とした手続き指向 (プロシージャ指向: procedure-oriented) の考え方をしたが、 その後の構造化設計法や構造化分析法の中でデータの分析や整理や命名法などを重視するデータ中心アプローチへと大きく揺れ動いた。 これはプロシージャ部分ばかりに関心をもっていた人々にショックを与えるものであった。 そして、その後のオブジェクト指向への関心が高まることによって、振り子は中庸に戻ってプロシージャ部分 (オブジェクト指向の用語ではメソッド) にもデータ部分にも配慮すべきであり、 こうすることによって一段高いレベルに立てるはずだというように進んできたのである。
オブジェクト指向では、階層的なクラス体系の中でオブジェクトという基本単位の位置づけが明確にされる。 そして、オブジェクトは、データとプロシージャとを、すなわち関係するものすべてを、いわばカプセルに入れた (カプセル化した) 独立性の高い塊になる。 カプセルの中に入れられたデータは、外部から見えないように情報隠蔽 (いんぺい) されることになり、内部の細かなことを知らなくてもオブジェクトを使うことができるような配慮がなされる。 つまり、従来のプログラミング方法では、かなり気をつけないと外部と内部の境界があいまいになりがちであったが、オブジェクト指向プログラミングでは外部と内部の境界を明確にせざるを得なくなくなり、あいまいさがなくなって分かりやすくなる。 このことによって、カプセルの中に入れられたデータに関するメソッド (すなわちプロシージャ) が独立性の高い塊の中に集められるという効果もある。 従来は気をつけないと、ある一つのデータに関する同じようなプロシージャが何個所にも散在することになりがちであったが、オブジェクト指向では一つの塊の中に集中させられることになる。
具体例を挙げると、“商品”というエンティティをオブジェクトにした場合には、その属性を表わすデータ項目“商品名称”とか“商品単価”は情報隠蔽して、見えなくする。 そして、“商品を仕入れる”とか“商品を発送する”といような商品に関するメソッドを用意して、商品に関する処理はすべてこれらのメソッドを通して行うことになるのである。
単なるエンティティの中には、その属性 (アトリビュート) を表すデータ項目が含まれているが、プロシージャは含まれていない。 これに対して、オブジェクトには、データもプロシージャも含まれていて、これらがカプセル化されている。 データとプロシージャを総合的に捉らえようとするところに進歩があるのだと言える。 オブジェクトのこのような点が単なるエンティティとは異なるのである。
なお、“オブジェクトの二つの候補”という意味が分かり難いと思われた方のために補足説明をしておく。 データ項目をオブジェクトに対応づけるということは、データ項目に対してメソッドをつくるというデータ項目を主体にした見方をすることである。 そして、エンティティをオブジェクトに対応づけるということは、エンティティに対してメソッドをつくるというエンティティを主体にした見方をすることであり、データ項目を公開しないこと (すなわちプライベートな属性にすること) を意味する。 データ項目を公開してしまうと、情報隠蔽の効果が薄れてしまい、オブジェクト指向の枠組みを無視することになってしまうからである。
オブジェクト指向にあまり関心のない方、または退屈だと感じた方は、以下を飛ばして 「2.2.2 データ項目をオブジェクトに対応づけると」 に進んでいただきたい。 こうしても、その後の説明を理解するのにほとんど支障ない。
上の文は、構造化プログラミングに反して、いわば go to 文に相当するものであるが、このような文はわずかしか出現しないので、許していただきたい。
従来エンティティだと捉らえていたものを、見方を変えてオブジェクトとして見直すことは進歩に違いはないのだろう。しかし、こうすることで、果たして部品化アプリ再利用システムのどのような効能がどれだけ豊かになるというのだろうか? オブジェクト指向という考え方を意識しながら部品化アプリ再利用システムの検討を進める中で、 この点に検討メンバの関心が集まった。
オブジェクト指向の効能として、再利用性を高めるとか、大規模開発を効率化するとか、信頼性を高めるとかといった一般的な説明がなされているが、こういう抽象的な言い方ではその効能の程度が分からない。 しばしば生産性の向上というぎょうぎょうしい説明が 0.1%程度の向上を意味することがある。 このようにほんの少ししか効果がないのでは、あまりありがたくない。 ましてや、オブジェクト指向のためのオブジェクト指向では意味がない。 厳しい見方をすれば、従来の考え方やモデルによって、十分に実現できることであれば、オブジェクト指向の手柄だとみなすべきではないだろう。 したがって、従来と比較した、具体的な効能は、部品化アプリ再利用システムにとって一体全体何なのかという点が問題になったのである。
結論を言うと、部品化アプリ再利用システムの検討の中で、オブジェクト指向の効能を一つだけ見出すことができた。 従来から部品化再利用システム SSS や何らかの方法で実現できていたものを取り除き、さらに目に見える効果のないものを取り除いていくと、この他には見つけることができなかった。 ただし、見つけることができた効能は、かなり価値のあるものであった。
カスタマイズ作業の手順が洗練されたものになる
図2-1: 部品化アプリ再利用システムにとってのオブジェクト指向の効能
その効能とは、オブジェクト指向の仕組みを用いることによって、部品化アプリ再利用システムにおいて、よくあるタイプのカスタマイズの手順を洗練された仕様にできるという点である。 どのようなカスタマイズの手順を洗練された仕様にできるのか、(商品エンティティ、いやこれより一段高いレベルの) 商品オブジェクトの例を取りあげて具体的に見ていこう (図2-1 参照)。
オブジェクト指向では、設計時に各オブジェクトの性格づけを行うために、それぞれのオブジェクトにいくつかの属性 (すなわちインスタンス変数) をもたせる。 こうすることは、そのオブジェクトに対してどのような処理が可能かという範囲を決めることにもなる。 商品オブジェクトについても、設計時に熟考してどのような属性をもたせるのかを決める。 たとえば 「商品名称」 とか 「商品単価」 などの属性は、大抵の処理に必要だから、これらは商品オブジェクトに必須の属性として最初から組み込んでおくことだろう。 このように商品オブジェクトにもたせるべき属性の大半はあらかじめ洗い出すことができる。 しかし、必要になる属性のすべてを見通すことはできないので、必要だと分かったときに属性を追加するカスタマイズ作業も必要になる。 たとえば、食品業者が取り扱う商品には、「商品の賞味期限」 という属性を特別に必要とするかもしれないし、電化製品量販店の C 社は、電気の供給が 50 Hz と 60 Hz の両地域に顧客をもつために、 どちら向け (あるいは両用・切換え不要) に初期設定されているのかという 「商品の対応電源種別」 という属性を特別に必要とするかもしれない。 このように、特種な属性が必要だと分かったときに、カスタマイズ作業を行って、商品の属性を追加することがしばしば必要になる。
この種のカスタマイズ作業は、オブジェクト指向の仕組みを用いると洗練された仕様にすることができる。 理想的には、商品の属性の追加・変更・削除に伴い、メソッド (プログラムのプロシージャ部分) の追加・変更・削除も一緒にできると良い。 この理想が、正にオブジェクト指向の仕組みを用いることによって実現できるのである。 なぜなら、オブジェクト指向では属性とメソッドとをまとめてカプセル化することになっているからである。
この他にも都合のよいことに、次のようなクラス階層を設けることによって、継承というオブジェクト指向の再利用の機構を活用する道が開けてくる。 つまり、「商品名称」 や 「商品単価」 などの属性を含んだ“商品オブジェクト”のサブクラス (子クラス) として“食品業者の商品オブジェクト”や“電化製品量販店の C 社商品オブジェクト”を定義すれば、 商品オブジェクトの属性 (すなわちインスタンス変数) やプロシージャ (すなわちメソッド) を継承できる (すなわち再利用できる) ことになる。
このようなオブジェクト指向の仕組みを用いることによって、部品化アプリ再利用システムの中のオブジェクトの属性に関するカスタマイズの方式を洗練された仕様にできる。 なお、SSS ツールにおいては、整理が不十分であったため、この種のカスタマイズ作業は力ずくの手作業で行うしかなかった。 これまで改良すべきか課題として SSS ツールが抱えていたこの問題を解決できるだけでなく、洗練された仕様にできるのである。
「何をすればオブジェクト指向のテクノロジーを適用したと言えるのか?」 という問いがしばしば話題にのぼる。
Smalltalk こそが純粋なオブジェクト指向なのだから、Smalltalk 言語で記述しないと本当の意味でオブジェクト指向のテクノロジーを適用したことにならないと厳しく言うその道の信者もいる。 そこまでいわずに、何らかのオブジェクト指向プログラミング言語で記述すれば、そのテクノロジーを適用したことになると言う人もいる。 これらは、プログラミングを重視する人々の意見である。
これとは対照的に、オブジェクト指向分析法や設計法を重視する人々は、オブジェクト指向の考え方に沿って分析や概要設計を行い、その精神に則ってプログラミングをすれば、たとえオブジェクト指向プログラミング言語を用いなくてもそのテクノロジーを適用したことになるとの意見である。 そして、分析や概要設計を重視する人々は、プログラミング重視派の言うことは誤っていると言って、オブジェクト指向プログラミング言語 C++ を用いて、オブジェクト指向のテクノロジーを全く使用せずにプログラムが作れることを示したりする。
このように、オブジェクト指向のテクノロジーを適用するとは何かに関して、必ずしも意見がまとまっているわけではない。
部品化アプリ再利用システムのフレームワークの検討では、オブジェクト指向の考え方に沿って分析や概要設計を行ったが、 その製品版の RRR ファミリーはオブジェクト指向プログラミング言語を用いてはいない (なお、最新版では Java や VB.NET などのオブジェクト指向プログラミング言語を用いるようになった)。 したがって、部品化アプリ再利用システムあるいは RRR ファミリーにオブジェクト指向のテクノロジーを適用したというべきかどうかは、前述のどの立場をとるのかによって変わってしまう。 そこで、本書では 「部品化アプリ再利用システムのフレームワークの検討においては、オブジェクト指向という考え方を強く“意識”した」 というような言い方をしている。 なお、このような表現をしているのは、本書がオブジェクト指向に関する評価をできるだけ正確に率直に書こうとしているからである。
ちなみに、もしも RRR ファミリーなどの商品のキャッチコピーであれば“オブジェクト指向”という枕詞を付けることに、筆者はいささかの抵抗も感じない。 宣伝文句の中では、そういった修飾語の使い方は、もはや常識になっているからである。
話を元に戻そう。 RRR ファミリーの開発になぜオブジェクト指向プログラミング言語やオブジェクト開発支援ツールを用いなかったのかというと、適切なものを見つけることができなかったからである。 もしも属性の追加・変更・削除に関するカスタマイズ作業を洗練された仕様にするだけでよければ、オブジェクト指向プログラミング言語を用いることもできた。 しかし、そうするといろいろな点で、ぎくしゃくしてくる。 まるでオブジェクト指向システムに異邦人として取り扱われているような疎外感にさいなまれるのである。 ビジネス分野では、当然こうあるべきだという常識が、オブジェクト指向システムの世界では通用しない。
たとえば、オブジェクト指向の継承機構を使って属性の追加・変更・削除に関するカスタマイズ作業を行うと、それに連動してファイルやデータベースの変更がなされて、性能のよいアクセスができるようには、残念ながら設計されていない。 カスタマイズを施すとアクセス性能が落ちるようでは実用に供しないので、この種のカスタマイズを行った場合に性能上の問題を起こさないことが重要である。 ところが、この要件を満足するオブジェクト指向開発支援ツールを見つけることができなかった。
ここでは、オブジェクト指向システムが性能に無頓着だと主張しているのではない。 一般にハードウェアの性能を見ると、CPU のスピードやメモリの容量やディスクの容量の進歩に比べて、ディスクへのアクセススピードの進歩が極端に低いので、どうしてもここが性能のボトルネックになりがちである。 したがって、このネックをソフトウェアでカバーするためにいろいろな工夫がなされている。 たとえば、オブジェクト指向データベースの性能向上策として、関係するすべてのデータをあらかじめメモリに読み込んでおき、データが変更されてもいちいちディスクに書き出すことはせずに高速に処理して、1日分の処理が終わったときになどに一括してディスクに書き出すことで、ディスクへのアクセス負荷を軽くする方式を採用しているものもある。 このように性能に対する配慮はいろいろなされている。
ところが、ビジネス分野においては、各伝票を処理するごとにディスクなどの不揮発性媒体にデータを書き出すことが必要なので、上記の方式は採用できない。 オブジェクト指向システムの性能を向上させる方式を検討する際には、ビジネス分野での使い方に焦点を定めて、それにふさわしい方式を採用して欲しいのであるが、それがなされていないのである。
適切なオブジェクト指向開発支援ツールを見つけることができなかったので、仕方なくファイルやデータベースへのアクセス性能に配慮した継承機構を自ら開発することにした。 なお、この開発に当たっては、オブジェクト指向のすべてを実現したのではなく、ビジネス分野の特性を考慮して、ほとんど必要ないと思われるところは縮退させた専用の機構にした。 いろいろ試してみたいところであるが、費用と効果を考えるといたしかたのないことである。
RRR ファミリーの開発においては、ビジネス分野に関係のない機能を縮退させたが、逆にビジネス分野向け必要な機能を拡張した。 主な機能拡張の一つは、前述のような属性の追加・変更・削除に伴うカスタマイズに関係するものである。 すなわち、プロシージャを継承する際に、その継承率を高くするための改良を施した。
この仕掛けを理解いただくには、オブジェクト指向に関するある程度の知識が必要であるので、その辺りの説明から始めよう。
オブジェクト指向の用語の一つに差分プログラミングがある。 これが意味するのは、サブクラス特有のプロシージャ (メソッド) を差分として記述しさえすれば、後は黙っていても親クラスのプロシージャが継承される (再利用できる) ということである。 つまり、差分プログラミングはオブジェクト指向における再利用のための重要な機構なのである。
正統的なオブジェクト指向では、クラス内のプロシージャ (メソッド) が継承の単位であり、かつ再利用の単位だということになっている。 ところが、部品化アプリ再利用システムの検討の中で、少なくともビジネス分野ではよくある前述のようなカスタマイズの際には、問題があることが分かった。 すなわち、再利用の単位が大き過ぎて再利用率が上がらないのである。 再利用の単位は差分プログラミングの単位でもあるので、そういう塊でそっくりそのまま再利用できない場合は、実際の差分だけでなくそのプログラム全体 (再利用の塊すべて) を記述することが必要になる。
一般的には、再利用の単位を小さくした方が、差分としての記述を必要とするプログラムの行数が減り、再利率は高くなる。 だからといって、再利用の単位を小さくすればよいということではない。 これを小さくし過ぎると、基本単位が細かくなりすぎて全体を把握することが難しくなってしまう。 したがって、正統的なオブジェクト指向では、再利用の単位をクラス内のプロシージャだとしていることも、十分にうなずける。
オブジェクト指向が有効かどうかを評価する際には、現実世界を分かりやすくモデル化できるかどうかということと、プログラム(プロシージャ)が再利用しやすいかどうかということの二つが重要なキーである。 前者のモデル化にとっては、エンティティに対応づけられたクラス内のプロシージャを継承の単位にすることが望ましいのであるが、後者の再利用にとっては、少なくともビジネス分野に関する限り、しっくりこない。 なぜなら、ビジネス分野でよくあるようなカスタマイズに関するかぎり、ほとんどの場合、差分プログラミングの単位はエンティティよりも細かなデータ項目に対応したものだからである。
そこで、RRR ファミリーにおいては、エンティティに対応づけられたプロシージャをさらにデータ項目に対応づけて細分化することによって、データ項目対応のプロシージャなるものをつくり、これを差分プログラミングの単位 (すなわち再利用の単位) にするのがよいという結論になった。 そして、実際にこうすることによって、継承による再利用率を大幅に向上できた。
以下では、オブジェクト指向に関して詳しい方、あるいは興味を持たれている方を対象にして、かなり細かな議論を展開している。 これらの議論に興味がない方は、以下を飛ばして 「2.2.2 データ項目をオブジェクトに対応づけると」 に進んでいただきたい。
ビジネス分野でよくあるようなカスタマイズは、エンティティよりも細かなデータ項目に関するものである。 そして、データ項目に関するカスタマイズにおいては、データ項目対応のプロシージャを追加したり、置き換えたりできる方が再利用率を上げることができる。
たとえば、商品の属性を表示するというメソッド (オブジェクトのクラスに対応づけられたプロシージャ) は、もしも商品オブジェクトに新たな属性を追加・変更・削除するというカスタマイズを行うと、その影響を受けて異なるものになってしまう。
具体的には、“商品オブジェクト”のサブクラスの“食品業者の商品オブジェクト”向けに、「商品の修理受付窓口」 という属性を削除し、 「商品の賞味期限」 という属性を追加するというカスタマイズを取りあげてみよう (図2-2 参照)。 このカスタマイズを実施すると、商品の属性を表示するというメソッドにおいては、商品の修理受付窓口の表示を止めて商品の賞味期限を表示することが必要になる。 したがって、“商品オブジェクト”のメソッドをそのまま継承することはできない。 商品の属性を表示するというメソッド全体を“食品業者の商品オブジェクト”用に新たなメソッド (プロシージャ) として記述しなければならなくなるのである。
ほんの少しの違いがあるために、違う部分も含めたかなり大きなプロシージャ全部を新たに記述する必要があるというのでは効率的ではない。 もっと継承率 (再利用率) を高くしたいものである。 そこで採用したアイデアは、商品の属性を表示するという大きなメソッドを細分化してデータ項目対応の“小メソッド”にすれば、個々の小さな塊はカスタマイズ作業の影響を受けることが少ないので、継承率を高くできるはずだというものである。
実際にメソッドをデータ項目に対応づけて細分化すると、商品名称を表示するとか商品単価を表示するというような“小メソッド”になるから、そのほとんどは“食品業者の商品オブジェクト”用にも使えるものとなり継承できることになる。 したがって、新たに記述しなければならないのは、これまで存在しなかった商品の賞味期限を表示するというような“小メソッド”だけで済むことになる。 そして、こうすることによって、継承率を大幅に向上できるのである。
図2-2: 商品の属性を追加・削除するカスタマイズ例
RRR ファミリーにおけるビジネス分野向けの拡張とは、データ項目に対応づけて細分化されたデータ項目対応のプロシージャ、すなわち“小メソッド”をビジュアルな簡単な指定で取り扱えるようにしたものである。
継承率を上げるという問題について観点を変えて検討すると、本質的には、何をメソッドとすべきかという考え方に関係していることが分かる。 そして、何をメソッドにすべきかを突き詰めていくと、何をオブジェクトにすべきかという最初の問題にもどってしまう。 このことをもう少し詳しく説明しておこう。
一般にオブジェクト指向では、クラス内のプロシージャのことをメソッドだとしている。 そこで、もしもデータ項目をオブジェクトに対応づければ、メソッドとは最初から特定のデータ項目に対応するプロシージャだということになる。 したがって、大きなメソッドをデータ項目に対応づけて細分化するような必要はない。
このような議論を展開すると、何をオブジェクトにすべきかという最初の問題に戻ることがお分かりいただけるだろう。 データ項目をオブジェクトに対応づけることは、次の項 「2.2.2 データ項目をオブジェクトに対応づけると」 で検討することにして、 この項ではあくまでもエンティティをオブジェクトに対応づけた場合について考察する。 こうしないと堂々巡りの議論になってしまうので、それを避けることにする。
とは言っても、たとえエンティティをオブジェクトに対応づけるという前提があったとしても、以下の2点は何が違うのかという疑問がわくかもしれない。
(D) 大きなメソッドをデータ項目に対応づけて細分化するということ
(S) 商品名称を表示するとか商品単価を表示するとかというデータ項目に対応
づけた“小メソッド”を最初からメソッドだと捉らえること
(D) のようにすることによって継承率を高めることができるということは、上述のとおりである。 もしそうなら、最初から (S) のようにデータ項目に対応づけた“小メソッド”を最初からメソッド (継承の単位) にしても同じことではないのかという疑問がわいてくる。
この疑問に答えるには、メソッドの意味付けをする人が、開発のどの段階にいるのかを明確にしなければならない。
もしも、分析や概要設計の段階にいるのなら、全体を見渡せるように見通しを良くすることが重要である。 したがって (S) のようにすることはとんでもないことなのだ。 なぜなら、このようにすると、ビジネス分野ではメソッドの数が莫大なものになってしまい、分析や概要設計の見通しが悪くなってしまう。 データ項目ごとに、それを表示したり変更したりするメソッドが出現するので、データ項目の総数の数倍のメソッドと格闘せざるを得なくなる。 ビジネス分野の業務プログラムが取り扱うデータ項目は、数百から数万に及ぶ。 したがって、その数倍のメソッドを意識しながら分析や概要設計を行わなければならないことになる。
こんなことになっては困るので、分析や概要設計の際には、エンティティに対応づけたプロシージャをメソッド (継承の単位) にするのである。 ただし、エンティティは、通常、データ項目よりも大きな単位なので、メソッドも大きな塊になってしまい、これを細分化しないことには、カスタマイズ作業の際に継承率を上げることができないというのが、先の疑問に対する答えである。
何をメソッドにすべきかを突き詰めて追求すると、オブジェクト指向の枠組みに従ったモデルがビジネス分野にもぴたりと合うのかという点が問題になる。 現状のオブジェクト指向では、クラス内のプロシージャのことをメソッドと呼び、これを継承の単位にしている。 これが適切かどうかという根本的な問題が浮上してくることになる。
ここでオブジェクト指向を擁護しようとするつもりはないが、継承の単位、すなわちメソッドがオブジェクトのクラスに含まれるのは、妥当なことだと思う。 オブジェクト指向においては現実世界のモノとの対応関係を重視するので、そのモノに関係するメソッドを継承の単位にしているのである。 もしも、オブジェクトよりも細かな塊を勝手にこしらえて、メソッドをそれに対応させたとしたら、オブジェクトの意味があいまいになってしまうことだろう。
ところが、ビジネス分野では少し様子が違っていて、ある場合にはエンティティ (に対応づけたオブジェクト) よりも細かな塊 (データ項目) を無視したくなるのであるが、別の場合にはそれが明確な意味をもつ場合がある。 すなわち、分析や概要設計の段階では、全体を見渡せるように見通しを良くすることが重要なので、エンティティをオブジェクトに対応づけるのが分かりやすい。 ところが、カスタマイズ作業においては、メソッドをエンティティよりも細かなデータ項目に対応させないと、メソッドの継承率を高くできない。 したがって、カスタマイズの局面においては、エンティティに対応づけたメソッドだけではなく、データ項目対応づけたメソッドも必要になるのである。
トピック 3: インスタンスに関係して
ここでは、オブジェクト指向のインスタンスという概念に関係する二つの話題を取りあげる。
その一つは、商品オブジェクトのインスタンスとは何かを考える中で発見したオブジェクト指向の副次的効果に関する話である。
たとえば画廊という業種の業務プログラムについて考えてみると、商品オブジェクトのインスタンスとは個々の絵画を指し示すのが普通である。 ここで、絵画の中でも版画を取り扱う場合には、通常の絵画とは少しばかり違いがある。 版画は一つの作品に対して何枚かのコピーが刷られるものだから、次の二つの取り扱い方法があり得る。
・ 作品の各コピーを個別にインスタンスにする (各コピーに注目する)
・ 作品の種別をインスタンスにする (各作品種別に注目する)
番号が書かれサインされた個々の版画のコピーを別々の商品として取り扱いたいのであれば、作品の各コピーを個別にインスタンスにすることだろう。 そうではなく、個々のコピーを区別せずにマスとして捉らえて、いくつの在庫があるのかだけに関心をもつのであれば、作品の種別をインスタンスにすることだろう。 すなわち、一つの作品の各コピーを一括して同じ一つの商品だとみなすのである。
このように、どこまで区別したいのかによって何をインスタンスにするのかを決めるのが普通である。 したがって、文房具の卸業の業務プログラムにおいては、たとえば A 社製の B123 という種類の鉛筆のように商品の種別または種類 (あるいは特定の商品の集合) をインスタンスに対応づけるのが普通である。 個々の鉛筆一本一本を商品オブジェクトのインスタンスにするようなことは、めったにない。
一般に、何をインスタンスにするのかを曖昧にしておくと、業務プログラムを大勢で開発する際に誤解が生じて混乱のもとになる。 もしも開発者がオブジェクト指向の用語を知っていれば、インスタンスという専門用語を使ったコミュニケーションができるので、開発者の相互理解に役立つ。 この効用を少しばかりぎょうぎょうしく評すると、オブジェクト指向がある枠組みを設定してあり、その用語の意味を明確にしていることによる副次的効果だといえる。
インスタンスに関係して取りあげるもう一つの話は、ビジネス分野向けにオブジェクト指向の機能チューニングの重要性である。
オブジェクト指向プログラミング言語を用いると、ごく自然に各インスタンスを識別するためのユニークな識別子が付けられる。 たとえば、商品オブジェクトの各インスタンスには、他の商品インスタンスと区別するための識別子が付けられるようになっている。 これはなかなか便利にみえるのであるが、そうでもない。 ビジネス分野では従来からユニークな識別子として商品コードのようなコード体系を用いているので、同じようなものが二つできてしまう。
従来どおり商品コードのようなコードを使い続けるのでは、識別子が2種類存在することになり、重複するので無駄である。 いや、無駄なだけではなく、同じような役割のものが二つ存在するために混乱することになりかねない。 したがって、商品コードは止めにしてインスタンス識別子だけに一本化したくなる。
ところが、インスタンス識別子は、大抵の場合、オブジェクト指向システムが勝手に付けるものなので、商品コードのように前もって体系化できない。 また、識別子はパーシステントでない (持続性がない) ことが普通であり、アプリケーションプログラムを起動する度に、異なる識別子が付けられるおそれがある。 この二つの理由によって、インスタンス識別子はビジネス分野では使い難いのである。
オブジェクト指向システムの内部に立ち入って詳しく聞いてみると、どうも内部テーブルのメモリアドレスをインスタンス識別子にしているものが多いようである。 ビジネス分野における使い方などはお構いなしのようで問題である。 もしも、ビジネス分野にもオブジェクト指向を勧めるのなら、是非ともインスタンス識別子を従来の商品コードのように便利な使い方ができるものにすべきである。 あるいは、既に一部のオブジェクト指向システムでは実現されているように、識別子はあっても使わずに、商品コードのようなコードだけで大抵の処理ができるようにすべきである。
なお、オブジェクト指向データベースでは、識別子をパーシステントにしている点はよいのであるが、識別子を商品コードのように前もって体系化することはできない。 そして、この他にもビジネス分野での使い方への配慮に欠けるという問題点が見受けられる。 たとえば、ビジネス分野で必要になる排他制御やトランザクション制御との整合性に問題の多いものがほとんどである。
前項では、従来からビジネス分野で注目されていたエンティティをオブジェクトに対応づけて、オブジェクト指向の考え方を意識しながら部品化アプリ再利用システムの検討や分析を進めたという話をした。 この項では、もう一方のデータ項目をオブジェクトに対応づけたらどうかという検討結果の報告をする。
データ項目をオブジェクトに対応づけることは、SSS の特徴であったデータ項目に重要な役割をもたせるという考え方に合致するので好都合である。 しかし、通常のオブジェクト指向分析による対応づけとは異なってしまうので、いかがなものかという戸惑いがあった。 あまりにも即物的で、理論的な根拠が薄弱なのではないかという点が気になったのである。
ところが、一般にビジュアル開発支援ツールにおいては、データ項目に近いものをオブジェクトに対応づけていることが分かった。 したがってオブジェクトをデータ項目に対応づけることは、前例のないことではないという安心感を得た。 また、RRR ファミリーの開発においては、何らかビジュアル開発支援ツールを使おうと考えていたので、「ビジュアル開発支援ツールとの整合性が良いのは好都合」 ということで、データ項目への対応づけという方向に検討メンバの賛同が集まっていった。
GUI (graphical user interface) とは、ウィンドウの中に配置した各種のボタンやメニュー項目やリストボックスやテキストボックスなどの GUI コントロール (または widget とも呼ばれる) を用いたビジュアルな操作方法のことである。 GUI は、ゼロックス社のパロアルト研究所 (PARC) で生まれて、アップルコンピュータ社のマック (Macintosh) で大きく成長して、マイクロソフト社の Windows で商業的な成功をおさめている。 GUI に関するソフトウェアは、GUI コントロールをオブジェクトとして捉らえることで成功しており、オブジェクト指向の申し子のような存在である。 ここでは、オブジェクト指向の成功事例として、GUI に関するプログラムを取りあげてみる。
GUI の操作は、オブジェクト指向的であるといわれることがある。 こういわれるのは、以下のように GUI 操作とオブジェクト指向の枠組みとがぴたりと対応づくからである。
GUI 操作は、「メニュー項目にクリック操作を施す」 とか 「アイコンにダブルクリック操作を施す」 とか 「ボタンにクリック操作を施す」 のように、「〜 に 〜 操作を施す」 という形で表せる。 ここで、メニュー項目とか、アイコンとか、ボタンという GUI コントロールをオブジェクトに対応づけると、「〜 に 〜 操作を施す」 という操作は、「オブジェクトに 〜 操作を施す」 という形になる。 そして、この 「〜 操作を施す」 というところを、オブジェクトのもつメソッドに対応づけると、上の例は、うまいことにすべて 「オブジェクトにメソッドで規定される操作を施す」 と表現できる (注3)。
このように、GUI における操作は、オブジェクト指向の枠組みとぴたりと合っているので、GUI ではオブジェクト指向のテクノロジーを活用するのが定番になっている。
注3: 一般に、このような分かりやすい対応関係が存在すると、すなわちプログラム (の断片) と現実世界のモノとがぴたりと対応づくと、そのモノに対応するプログラムの断片は、識別しやすい塊になり、部品と言えるようなものにしやすい。
たとえば、SSS 部品セットの各部品はデータ項目と対応づけることができるので、プログラムを分かりやすい単位 (データ項目部品単位) に分割できる。
また、GUI 操作のプログラムは 「オブジェクトにメソッドで規定される操作を施す」 という形の GUI 操作と対応づけることができるので、プログラムを分かりやすい単位 (部品と言えるようなもの) に分割できる。
一般に、GUI 操作に関係するプログラムは、オブジェクト指向のテクノロジーを用いており、各種の GUI コントロールをオブジェクトに対応づけ、それに関する操作をメソッドに対応づけている。 そして、操作者がある GUI コントロールにある操作を施すと、その GUI コントロールのその操作に対応するメソッドが動作する仕組みになっている。
図2-3: GUI の操作ベースと GUI 操作の処理プログラム
GUI 操作に関係するプログラムの構成を調べてみると、GUI コントロールというオブジェクトに対応するものと、そうではないもの (たとえば、制御を渡す役割をもつもの) の2種類に分類できる。 そして、前者は、すなわち GUI コントロールに対応しているプログラムは、そのオブジェクトのそれぞれのメソッドに対応づけて分割できることが分かる。
本書では、図2-3 のように、前者の部分を GUI 操作の処理プログラムと呼び、 オブジェクトに対応しない後者を GUI の操作ベースと呼ぶことにする。 一般に、オペレーティングシステム (OS) の上で動作するアプリケーションプログラムのことを処理プログラムと呼ぶが、これにならって、GUI 操作に関するプログラムも上記のように二つに分類してみる。
こう分類すると、GUI 操作の処理プログラムは、対応するオブジェクトのメソッド群とぴたりと対応づくことになる。 そして、GUI の操作ベースは、操作者がある GUI コントロールにある操作を施すと、その GUI コントロールのその操作に対応するメソッド (GUI 操作の処理プログラム) に制御を渡す (呼び出す) 働きをするものだと言える。 さらに言うと、GUI の操作ベースは、メソッドが動作する仕組みを実現するプログラムであるということもできる。
ある目的を果たすプログラムを開発する際に、操作性に気を配って GUI を採用することにしたとしよう。 ところが、この種のプログラムを一から開発すると大仕事になる。 なぜなら、その目的を果たすプログラム (業務処理に関係するプログラム) も開発しなければならないし、さらに GUI の操作ベースも処理プログラムも開発しなければならないからである。 これらの開発作業を簡単に済ませるためには、どこかで開発された GUI の操作ベースや処理プログラムを再利用できると好都合である。
一般的に言うと、プログラムの再利用には解読を伴うので、再利用は大変に面倒なのであるが、オブジェクト指向のテクノロジーを用いた GUI の操作ベースと処理プログラムであれば、簡単に再利用できる。
具体例を挙げると、メニュー項目 X にクリック操作を施したときに行うべき処理のほとんどは、GUI の操作ベース、およびクリック操作メソッド (の標準的な処理を行う GUI 操作の処理プログラム) にまかせることができる。 メニュー項目 X にクリック操作を施した場合にも、メニュー項目 Y にクリック操作を施した場合にも必要とする共通処理は、GUI の操作ベース及びクリック操作メソッド (の標準的な処理を行う GUI 操作の処理プログラム) が行うことになっているものである。 したがって、メニュー項目 X のクリック操作に限って特別に行うべき処理に関係するプログラムだけを作ればよいことになる。 すなわち、業務処理のプログラムだけを作成すればよいのである。
これをさらに詳しく言うと、メニュー項目のサブクラスとしてメニュー項目 X を設けて、その業務処理部分のプログラムをメニュー項目 X の業務処理用クリックメソッドとして記述する。 こうすると、メニュー項目 X のメソッドは、原則としてメニュー項目のメソッドが継承されるが、業務処理用クリックメソッドだけは、そこで差分として記述したプログラムが使われる。 つまり、差分だけのプログラムを記述すれば済むという (差分プログラミングの) 恩恵にあずかれることになる。
別の見方をすると、GUI 操作の処理プログラムに対してプログラムカスタマイズを施すときに、オブジェクト指向のテクノロジーの恩恵によってそれが簡単になるのだということもできる。
繰り返しになるが、オブジェクト指向のテクノロジーを用いると、再利用がしやすくなるものである。 プログラムを新規に開発する際には、何をオブジェクトに対応づけるのかという設計が必要になるなど面倒な点もあるが、確かに再利用はしやすくなるのである。
世の中には、ビジュアル開発支援ツールが何種類も出回っている。 これらは、上記の差分プログラミングの仕組みを備えていて、GUI の操作性を備えたプログラムを非常に簡単に開発できるようにしている。
ビジュアル開発支援ツールでは、業務処理用クリックメソッドのような差分として記述するプログラムのことをイベントプロシージャまたはイベントルーチンと呼ぶことがある。 イベントとは、たとえば 「クリック操作」 というような事象の発生のことであり、イベントプロシージャとは、そういう事象が発生したときに動作するプログラムのことである。 そして、ビジュアル開発支援ツールの中には、イベントプロシージャを記述するだけで、サブクラスを作るという処置が自動的になされるような便利な機構をもつものもある。 なお、イベントプロシージャについては、「3.2.2 第四世代言語」 で詳しく説明する。
このように、ビジュアル開発支援ツールは、ほぼオブジェクト指向の枠組みに沿っているが、正統的だといわれている Smalltalk 流のオブジェクト指向の枠組みと比べると機能を縮退したり、拡張したりしている部分もある。 これは使いやすいものにする努力だと好意的に見るべきだろう。
GUI とは、いわば操作者という舞台監督が、ウィンドウという舞台の上で GUI コントロールという俳優たちに演技を付けるものだと見ることができる。 こういう世界では、オブジェクト指向の枠組みがぴたりと合っていて、オブジェクト指向のテクノロジーが大成功をおさめている。
部品化アプリ再利用システムの検討の中では、この大成功にあやかるにはどうすればよいかを考えた。 というのは、RRR ファミリーの構成要素の 6 〜 7 割は、操作者が画面とのやり取りをするときに動作するものだから似たような世界に住んでいるはずであるし、 RRR ファミリーに GUI の操作性を取り入れることは必須だったからである。 そして、こうするには RRR 部品セットが取り扱う画面をウィンドウに対応づけて、さらに画面の中の入力用のフィールドをテキストボックス (GUI コントロールの一種) 対応づけるという設計にするのがよいと考えた。
実際に、あるビジュアル開発支援ツールを用いて試作をしてみたところ、機能的なチューニングが必要であるが、基本的にそのように設計することによって問題のないことが分かった。 すなわち、SSS の最大の特長である。 データ項目部品をビジュアル開発支援ツールのイベントプロシージャに対応づける方法が見つかったのである。 そして、この発見によって、SSS の良い点をすべて引き継ぐことができるという確信が得られた。 これについての詳細は、「3.2.3 SSS から RRR ファミリーへ」 の中の 「部品を区切る分割指針に関する改善点その2」 で説明する。
こうした設計にすることは、部品化アプリ再利用システムの検討に当たって掲げた 「SSS の特長を損なうことなく、かつできるだけ一般に流布している考え方やツールに沿うべきである」 という方針に合致する。 また、こう設計することによって、RRR ファミリーを比較的簡単に開発できることになる。 なぜならば、RRR ファミリーの構成要素の 6 〜 7 割に、出来合いのビジュアル開発支援ツールを適用できるので、その恩恵にあずかれるからである。
ところが、こう設計した結果を見てみると、RRR ファミリーのデータ項目は、オブジェクトとみなされてしまうことが分かった。 つまり、RRR ファミリーの中のデータ項目は、基本的に業務プログラムの画面の中のデータ項目に対応しているので、 ビジュアル開発支援ツールはこれを GUI コントロールというオブジェクトだとみなしているのだ。
以前には、エンティティをオブジェクトとみなすのが良さそうだと考えていたのであるが、ビジュアル開発支援ツールを含めて検討しているうちに、データ項目がオブジェクトになってしまった。
この節では、部品化アプリ再利用システムの検討を通して、どのようにオブジェクト指向を捉らえるようになったのかを報告する。 そして、これまで検討してきたエンティティとデータ項目のどちらをオブジェクトに対応づけるべきかの結論を述べる。
オブジェクト指向の枠組みについては、既にその概要を 「2.2.1 エンティティをオブジェクトに対応づけると」 の 「進歩したと言えるのか」 で述べている。 ここでは、オブジェクト指向に関する評価を述べるための前準備として、オブジェクト指向の枠組みをもう少し詳しく説明する。 なお、オブジェクト指向に興味のない方は、ここを飛ばしても構わない。
オブジェクト指向の枠組みは、あやつり人形のように、手元の箱のレバーによってロボットの動作をコントロールするシステムを例に挙げてしばしば説明される。 こう説明するのが分かりやすいようだ。 したがって、ロボットをコントロールするシステムを思い浮かべていただきたい。 たとえば、高専や大学対抗のロボットコンテスト (ロボコン)、すなわちロボットに球技などを競わせる催し物が盛んになっているので、そういったものをイメージすればよいだろう。
このようなシステムを構築するには、ロボットにどんな振舞いをさせるのかということが重要なポイントになる。 したがって、まずはそれらを洗い出すことから始めることだろう。 オブジェクト指向の用語では、振舞いをさせるために必要なレバー操作のことをメソッドと呼ぶ。 この言葉を使って表現すれば、「メソッドを洗い出すことから始める」 と言える。 そして、各メソッドは、シュートするとか前進するとかというような、ロボットにさせたい振舞いの要素に対応づけられる。 つまり、手元の箱のレバー操作によって、このような要素的な振舞いをさせることができるようにするのである。
ちなみに、ビジネス分野の例を挙げると、販売管理システムの商品オブジェクトに関しては、取扱商品として登録するとか商品の属性を表示するとかというような要素的な処理をメソッドに対応づけることが普通である。
メソッドとは、プログラミングの世界での馴染みの言葉で言うと、オブジェクトに対してある処理をする (あるいはある振舞いをさせる) プロシージャのことだということができるし、もっと平たく言うと、 オブジェクトに関する何らかの処理をするサブルーチンのことだと考えても構わない。 正式に抽象的な言い方をすると、メソッドとは、オブジェクトの振舞い (behavior) を規定するものである。
オブジェクト指向では、データとメソッドとをカプセル化して (いわばカプセルに入れて) 総合的に捉らえるところに特徴がある。 これはデータとプロシージャをばらばらにしないための手段だとみることもできる。 そして、メソッドを通してしかデータの参照や変更ができないように制約を課している。 このことは、オブジェクト指向以外のところでも発展をとげた定評のある情報隠蔽 (いんぺい) の仕組みに他ならない。 これらのことを含めて、オブジェクト指向の枠組みは次のように言うことができる。
メッセージ (オブジェクト指向の用語であり、いわば手紙のような通信文) としてオブジェクト名とメソッド名とパラメタとを明記して発信すると、目指すオブジェクトにそれが伝えられて、指定したメソッドによって規定された操作が実施されることになる。 たとえば、商品の属性を表示するには、“商品”というオブジェクト名と、“商品属性表示”というメソッド名を明記したメッセージを発信すれば、その結果としてそのメソッドで規定された表示処理が実施されることになる。
メソッド以外には、オブジェクトを操作する方法はない。 したがって、オブジェクトの内部のインスタンス変数を直接操作したり参照したりすることはできない。 ロボットシステムを設計する際には、オブジェクトをどう操作したいのかを考えて、思いどおりにするために必要な操作は、すべてメソッドとしてあらかじめ組み込んでおくことが必要である。 したがって、オブジェクトを外から見ると、いわば手元のレバーという形で、メソッドが並んでいるのが見えるだけで、オブジェクト内部の複雑な内容は見えない。 これで済むようにうまく情報隠蔽されるのだ。 そして、各メソッドに関するパラメタは、あらかじめ決められているので、オブジェクトの外部インタフェースは、メソッドとそのパラメタだけであると言うことができる。 つまり、オブジェクトの振舞いの範囲は、どんなメソッドとパラメタを用意しておくかによって規定されることになる。
これは、ロボットに関する次のイメージと重ね合わせて理解するとよいだろう。 ロボットのコントロール用の手元の箱には、メソッドに相当するレバーが付いていて、操作者がレバーの設定を変えると、ロボットにメッセージが伝えられて、ロボットがある振舞いをする。 ロボットに対して外部からできることは、コントロール用の箱に付いているレバーの設定を変えることだけであり、外部インタフェースは何かということが明確になる。 ロボットの内部を直接的に操作したり観測したりすることは禁止されているのである。 したがって、ロボットに対してできる操作は、コントロール用の箱にどんなレバーが付いているかによって明確に決まることになる。
図2-4: オブジェクト指向の枠組み
ここに述べたことがオブジェクト指向の主な枠組みである (図2-4 参照)。 なお、これだけでなく継承という再利用の仕組みがあることは前述したとおりである。
このオブジェクト指向の枠組みは、次のような従来のソフトウェアにおける馴染み深い用語で表現することもできる。 ただし、以下の表現は、非同期的な動作をするアクタとかアクティブオブジェクトと呼ばれる特殊なものを除外して、通常の逐次処理だけを対象にしている。
オブジェクトは、その内部変数 (インスタンス変数) を集めた構造体と共通サブルーチン (メソッド) から構成される。 外部からは、その共通サブルーチンを呼び出すことができるが、内部変数を直接参照したり操作したりすることは一切許されていない。 つまり、外部からは、共通サブルーチンだけしか見えないように情報隠蔽がなされることになる。 こういう仕組みにするので、オブジェクトの外部インタフェースは、共通サブルーチンとそのパラメタだけだというように明確に決まる。 また、オブジェクトの振舞いは、どんな共通サブルーチンを用意しておくかによって明確に決まることになるである。
このような表現をすると、オブジェクト指向の抽象的な含蓄のある定義を冒涜するものだと非難する人もいる。 馴染みのある用語を用いると、それに染みついた色に影響されてしまい、その狭い範囲だけのものだと誤解されるおそれがある。 各用語と現実世界のいろいろなモノとの対応関係を固定観念に影響されずに実り豊かにしようとすると、広い解釈ができるような余地というか抽象性を残しておくことが重要なのだと言いたいのだろう。
こういう人がいる一方、オブジェクト指向の精神に則っていれば、実現 (インプリメント) の形態にこだわる必要なしと、馴染み深い用語での表現を擁護する人もいる。 たとえば、共通サブルーチンと言ったが、これは、関数かもしれないし、インライン展開されるマクロ命令かもしれないし、メッセージパッシングかもしれないし、 メッセージの待ち行列とそれを処理するプロセス (タスク) かもしれないし、... と実現 (インプリメント) の形を固定的に考えなければ、 馴染みの用語による表現も理解が進むのでよいではないかと、容認してくれる。 そして、逆にメッセージパッシングにこそオブジェクト指向の特徴があるというような言い方は、いかにも舌足らずであると批判したりする。 確かにメッセージパッシングには、知る人ぞ知る動的束縛 (dynamic binding) と呼ばれる進んだ機構が付いているが、そこにオブジェクト指向の特長が凝縮しているわけではない。
だいぶ細かくなってしまったが、詳細に説明すればするほどオブジェクト指向の本質とは離れていくような気がする。 細かなことまで書いた本はたくさんある。 しかし、本書よりももっと詳しく説明したとしても、それによってオブジェクト指向の効能が明確になることにはならない。 細かなことの説明の中では、小さな効能がしばしば大げさに扱われるから、オブジェクト指向の本当の良さがかえって見えにくくなるのではないだろうか?
ひるがえって、オブジェクト指向の本質を考えてみると、それは現実世界のモノとプログラムの対応関係を重視するところにあると思う。 そうだとすれば、細かなことを言えば言うほど、それにぴたりと合う現実のシステムが限定されてしまい、オブジェクト指向の恩恵に浴するチャンスが少なくなるような気がしてならない。 なお、このことに関係することを 「第6章 生物の進化と部品化再利用」 で論じる。
構造化プログラミングにおいては、その基礎のところで、すべてのプログラムの制御構造が while 文などの推奨パターンの組合せだけで記述できることが数学的に証明されている。 そして、こうした制御構造の標準化によって見やすいプログラムになるということを多くの人々が体験している。
これに対して、オブジェクト指向の場合はそうではない。 第一に、現実世界をすべてオブジェクト指向の枠組み従ったモデルで表現できることが数学的に証明されているわけではない。 第二に、オブジェクト指向の適用によって、現実世界のモノとプログラムの対応関係が分かりやすくなるなどの成功事例は確かに報告されているが、まだ大勢の人々が体験していることではないし、どんな場合にも成功するという保証はなさそうである。 分かりやすいかどうかは、主観的な要素が絡む証明しにくに問題だと認めたとしても、少なくとも具体的に納得のいく数多くの成功事例や失敗事例の報告が必要だと思う。 オブジェクト指向は抽象的で分かり難い面があるので、具体的な多くの事例があって初めて、どのようなケースにおいて (またはあらゆるケースにおいて) オブジェクト指向の適用がどのように効果的なのかということが明確になっていくのではないだろうか?
部品化アプリ再利用システムの検討 (オブジェクト指向を評価した事例の一つ) の中では、エンティティとデータ項目のどちらも、オブジェクトに対応づけるだけの十分な理由があるように思えた。
エンティティをオブジェクトに対応づけると、データ項目が情報隠蔽され、すっきりと見通しが良くなるのであるが、カスタマイズの際にはデータ項目を意識しなければならなくなり、情報隠蔽の効果がほとんどなくなってしまう。 逆に、データ項目をオブジェクトに対応づけると、カスタマイズに配慮した実現 (インプリメント) が可能であり、かつデータ項目単位の情報隠蔽もできるのであるが、分析や概要設計を行う際の見通しが悪くなるし、 エンティティ単位の情報隠蔽はほとんどできなくなってしまう (注4)。 したがって、分析や概要設計をする際には、エンティティをオブジェクトに対応づける方が良さそうであるし、ソフトウェアの実現 (インプリメント) 段階までくれば、データ項目をオブジェクトに対応づける方が良さそうである。
注4: オブジェクト指向プログラミング言語の中には、オブジェクトの中にオブジェクトを設けるというオブジェクト階層をサポートしているものがある。 オブジェクト階層を使うと、エンティティに対応づけたオブジェクトの中に、さらにデータ項目に対応づけたオブジェクトを設けるという二重の対応づけが可能。 しかし、二重の対応づけをしたとしても、ビジネス分野の使い方ではデータ項目というオブジェクトの公開 (すなわちパブリックにすること) が必要になって、結局エンティティ単位の情報隠蔽はほとんどできなくなることが普通である。 すなわち、データ項目をオブジェクトに対応づけた場合とほとんど変わりない。 したがって、本書では二重の対応づけをした場合について、データ項目をオブジェクトに対応づけた場合の中に含めて論じている。
オブジェクト指向には、クラス階層という概念があり、“商品”(エンティティ) というクラスのサブクラスとして“商品単価”(データ項目) を位置づけられるとよいかもしれない。 しかし、もしもこうすると、“商品”の属性に“商品単価”があるという分かりやすい関係が壊されてしまう。
こう考えて、エンティティかデータ項目かの二者択一をしなければならないと悩むことになった。
悩んだ結果の最終的な結論は、「どちらも意味があるので悩む必要なし」 ということになった。 なぜなら、業務プログラムの捉らえ方には、いろいろな視点があり、ある視点から見るとそれにふさわしいモデル化が可能であるが、そのモデルは、異なる視点からの最適なモデルとは限らないからである。
たとえば、ウイルスを生物と捉らえるべきか結晶と捉らえるべきかを考えてみよう。 こうした場合には、どちらの捉らえ方をするかによって、より深く理解するための概念体系 (すなわちモデル) は異なってくる。 生物という視点からは進化というモデルを用いて理解を深めることができるし、分子という視点からは結晶というモデルを用いて理解を深めることができる。 したがって、両方の捉らえ方をしてよいということができる。
これと同様に、要求仕様の明確化のためにビジネス分野の業務システムの背景となる業務の実態の分析や概要設計を行う際に見通しを良くするという視点で捉らえる場合と、 その要求仕様に基づく業務プログラムを再利用しやすい形態になるように実現 (インプリメント) するという視点で捉らえる場合とでは、それぞれにふさわしいモデルがあってもよいと考えたのである。 そして、前者の見通し良く分析や概要設計をするという視点からはエンティティをオブジェクトに対応づける方がふさわしいし、後者の業務プログラムを再利用しやすいように実現 (インプリメント) するという視点からは、 データ項目をオブジェクトに対応づける方がふさわしいという考えにたどり着いた。
なお、データ項目をオブジェクトに対応づけると、RRR ファミリーにおいて拡張しなければならないと想定した機能が、 すなわちクラス内のプロシージャをさらにデータ項目に対応づけて細分化する機能が、不要になると思われた。 しかし、実際には、この機能の代わりにデータ項目とエンティティを結び付ける機能が必要になった。 要するに、エンティティを主体にするかデータ項目を主体にするかという見方が変わっても、RRR ファミリーにおいては、この機能に関係する何らかの拡張が必要なことには変わりなかった。 必要な機能は、見方が変わっても必要だということなのだ。
オブジェクト指向に関係する用語は、それ独特のものが多いので、それらをきちんと理解することから始めて、オブジェクト指向なるものを意識しながら部品化アプリ再利用システムの検討を行った。 もしもこの検討をビジネス分野以外の分野を対象にして行っていたとすれば、すなわちオブジェクト指向が活躍しやすい分野を対象にして行っていたとすれば、オブジェクト指向に対してもっと違った印象を受けたかもしれない。 しかし、実際にはビジネス分野を対象にして検討を行ったのである。 いずれにしても、この検討を通してオブジェクト指向に関する何らかの感触を得ることができたのは確かである。 この章を終わるにあたり、この経験を通して感じたことをまとめておく。
まず、オブジェクト指向そのものについて言うと、一般には、オブジェクト指向の枠組みに従ったモデルを用いることが有効だと思う。 たとえば、GUI に関する分野はオブジェクト指向の枠組みにぴたりと合って効果を上げている典型である。 ただし、この枠組みだけでは個別の分野の事情に対処しきれないこともあり、その枠組みを各分野の事情に合わせていくための創造的な活動も必要なのではなかろうか? 特にビジネス分野に関しては、オブジェクト指向の枠組みではしっくりしないところがあり、ビジネス分野の使い方に焦点を定めた拡張が必要だと感じた。
次に、オブジェクト指向プログラミング言語を始めとするオブジェクト指向開発支援ツールについて言うと、ビジネス分野にとって都合のよい機能や性能のチューニングが十分に行われていないように見受けられた。 ビジネス分野では、オブジェクト指向のテクノロジーが使いやすくなっていないから使われないし、使われないから使いやすくならないという悪循環に陥っているのかもしれない。 そうでなければ、オブジェクト指向の歴史は 30 年以上もあるのだから、ビジネス分野においても、もっとオブジェクト指向のテクノロジーが使われていてもよいはずである。
別の見方からは、オブジェクト指向開発支援ツールにビジネス分野向けの機能的なチューニングを施していくと、汎用的なオブジェクト指向の枠組みが阻害されてしまうのかもしれない。 つまり、RRR ファミリーの開発で行ったように、オブジェクト指向の機能を縮退させてしまうと、オブジェクト指向の特徴が薄れることになる。 そして、第四世代言語 (4GL) などのビジネス分野に特化した開発支援ツールに近いものに収斂 (しゅうれん) 進化していくような気もする。
また、ツールベンダの立場を考えてみると、ビジネス分野向けのオブジェクト指向開発支援ツールなるものを販売するには、従来から存在するビジネス分野に特化した開発支援ツールとの競争になることは明らかである。 ところが、多くのオブジェクト指向開発支援ツールのベンダは、そうなることを避けて、別の市場をターゲットにしているようにも見受けられた。
最後に、商品の宣伝のためのオブジェクト指向という枕詞について言うと、オブジェクト指向のテクノロジーを全然使わなくても実現できることを実現させて、それがあたかもオブジェクト指向の手柄のようにまくしたてられることがあるので注意が必要である。 オブジェクト指向のテクノロジーを使わない場合に比べて、どんなことがどれだけ良くなるのか、実際の開発プロジェクトを例に挙げて、ベンダと議論することが必要だと感じた。 たとえば、クラスライブラリは通常のライブラリと何が違うのかとか、オブジェクト指向データベースはマルチメディアデータベースと何が違うのかとか、問いただして突き詰めて考えてみるのがよいだろう。 そして、何よりも言葉の響きに影響されずにその実体を把握するように努めることが重要である。 あるいは、オブジェクト指向という枕詞は無視してかかるのも一法かもしれない。
ここまで、オブジェクト指向についてだいぶページを割いてしまった。 これまで 「遅ればせながらビジネス分野においてもオブジェクト指向の有効性が確認されて ... 」 と繰り返しいろいろな宣伝がなされている。 しかし、宣伝する側からではなく、ユーザ側からの、しかも手を染めてしまったのだから賛同せざるを得ないという立場にない方々からの具体的な試みや評価の書きものが少ないように思う。 そこで、部品化アプリ再利用システムの検討の過程で捉らえたことを素直に書くことに価値があるだろうと考えて、かなり詳しくなってしまった。
うわさやうまい話やうわべのことだけでは、理解が深まらない。 具体例を示してそれを基に議論をすることが重要である。 そこで、できるだけ具体的に何を行って何を感じたのかを種々の観点から素直に書いたつもりである。 もしも、思い違いや見逃した点があれば、インターネットのメールなどを通してご指摘をお願いしたい。
p.s. ご意見をおよせください。
アプリテック株式会社
Copyright © 1995-2008 by AppliTech, Inc. All Rights Reserved.