【第19回】ECObjects技術解説講座 その1 -オブジェクト指向技術が目指すもの

一般的にオブジェクト指向技術というと、「難しい」「複雑だ」「自分には関係ない」「アカデミックな研究分野だ」というような苦手意識や距離感を感じて腰が引けている技術者が多いと思います。
ここでは、そうした方々のためにオブジェクト指向技術を平易に解説し、等身大の有効な手段として活用して貰うために、オブジェクト指向技術によるクラスライブラリの作成方法を、弊社のクラスライブラリの設計思想をもとに解説していきたいと思います。


・オブジェクト指向技術とは?
まずはじめに、オブジェクト指向技術とは何なのかについて、解説しておきましょう。オブジェクト指向技術の要素をまとめると以下のようになります。
1.カプセル化
2.クラスインスタンス
3.メッセージパッシング
4.インヘリタンス
5.ポリモーフィズム

オブジェクト指向技術を解説するのに一番重要な考え方が
1.カプセル化です。これは従来、部品化とか、モジュール化と呼ばれていた手法の一発展型です。どこが発展型かというと、データと手続きをある機能単位 にセットにしてモジュール化した点です。これによりプログラム実装を局所化して、ソフトウェアの部品化と再利用化を推進します。
オブジェクト指向はソフトウェア業界のツーバイフォー工法のようなものですから、部品化が主要なテーマとなるわけです。汎用的に供給される標準部品群をクラスライブラリと呼ぶのです。

2.クラスインスタンス、すなわちクラスとインスタンス(オブジェクト)とは何か?抽象的で一番分かりにくい概念ですが、これは、部品化という観点で考えると非常に明快です。
オブジェクト指向がソフトウェアを部品化(カプセル化)する技術だとすれば、その部品を量産するために、金型のような物が必要になるわけです。
それがクラスです。そのクラスを使って生成した部品が、インスタンスまたはオブジェクトと呼ばれる実体です。
オブジェクトを広い概念で捉えると確かに抽象的な世界に陥りますが、これはソフトウェアのためのパラダイムですから、野菜を作ったり、犬を飼ったりするような分野にまで概念を広げてはいけません。それこそ目的を失った説明になってしまいます。
さて、カプセル化、クラスインスタンスのしくみで、ソフトウェア部品化が実現されるわけですが、次に必要となるのはその部品をどういう順序・ルールで動かすかというしくみです。
そのしくみが、3.メッセージパッシング、4.インヘリタンス(継承)、5.ポリモーフィズム(多様性)という考え方です。これはどれも部品(カプセル)同士を非手続き的に連動させるしくみを提供します。

3.メッセージパッシングとはその名の通り、オブジェクトが他のオブジェクトにメッセージを送ることによって処理を起動するしくみで、現実にはメソッド を呼び出すことを指します。つまり、オブジェクト同士が話(パッシング)をするもっとも簡単な手段で、このメッセージのことをイベントと表現することもあ ります。

4.インヘリタンス(継承)とは、親となるクラスのインスタンスが持っている機能をそのまま受け継ぐという概念です。遺伝と似た機能で、駿馬ハイセイ コーの子供は訓練しなくても速く走る能力を親から受け継いで速く走れます。インヘリタンスも親から受け継いだ機能をそのまま実装します。
このメカニズムを利用することにより、親クラスからの差分だけを子クラスとして定義することでコードの二重開発を避け、親クラスとの差分をコーディングするだけで新しいクラスを導出することが可能になります(差分コーディング)

5.ポリモーフィズム(多様性)は、同一のメッセージが複数のオブジェクトごとに異なる働きをするメカニズムです。簡単に説明すると、家の電源(スイッチ)をONにすると、いろいろな電化製品はそれぞれ異なる動きをします。例えば、照明器具は光るし、テレビは映像を映し出すといった具合です。
また、実装時にはクラスごとに同じメソッド名が使用でき、とても便利な機能です。
オブジェクト指向をとりいれた言語の中でもこの機能を実現できていないものもあって、それを純粋オブジェクト指向じゃないとか、オブジェクト指向といえ ないと断定する人もいますが、カプセル化、クラスインスタンス、メッセージパッシング、インヘリタンスが最低限実現されていれば、クラスライブラリの開発は可能です。


・オブジェクト指向の目的と現在の問題点
今まで説明したオブジェクト指向の構成要素、カプセル化、クラスインスタンス、インヘリタンス、ポリモーフィズムなどは、何を目的としているのでしょうか。
それは、ソフトウェアの部品化と非手続き化です。それによって、何の恩恵があるかといえば、高生産性と高保守性を実現するということです。
逆にいえば、オブジェクト指向技術を応用して設計し、高生産性と高保守性を実現できなければ、設計の失敗ということになるわけです。
クラスライブラリやオブジェクト指向技術が現場から嫌われるもっとも大きな理由として、次の2つの原因が考えられます。

(1)言語の問題
オブジェクト指向開発というと、「純粋」「本格的」という理由から、SmalltalkやC++が対象言語として取り上げられるようですが、高生産 性と高保守性をビジネスアプリケーションの世界で実現しようとする試みに対して、これらの難解で保守性も生産性も著しく低い言語を採用すること自体、大き な矛盾があります。
最近の言語はたいていオブジェクト指向の技術を取り入れいていますので、もっとビジネスアプリケーションを記述するのに妥当な言語を採用するべきであると思います。

(2)継承の問題
例えば、AのクラスからBのクラスを継承させて、導出したBのクラスからまたCのクラスを導出しているとします。CのクラスはAとBのクラスを継承して いるわけですから、Cの差分だけをコーディングするだけでA+B+Cの機能を実現できると、「一般的には」説明されています。
現実的にはどうでしょう?Aが1,000ステップ、Bが1,000ステップであれば、Cの差分をコーディングするために、2,000ステップ分コードを解析し なくてはなりません。通常はもっと複雑な継承関係になるので、差分コーディングは一から組むよりも煩雑で難解な処理になってしまいます。何層にも深く継承 されるとロジックを追うことすら難しくなり、それが多重に継承されていると、もはや作った人間でもメンテナンス不能の正解に陥ってしまいます。


・要員と体制の重要性
クラスライブラリを作る人間(コンポーネントデザイナー)は、基本的に設計を知らないとだめです。設計ができて、なおかつ実装(プログラミング)ができるハイブリッドな人材でないとだめなのです。
クラスライブラリを効果的に標準化するデザインパターンの作成など、まさに設計センスで(大局観のある、プログラマ的でない)業務の標準化を成し遂げる スキルが必要です。複雑、膨大な抽象的なニーズを截然と構造化できる強い設計力と、驚くほど単純なフレームワークを導出できる創造力が必要です。
三流は簡単な物を複雑難解に作ります。二流は複雑なものを複雑に作ります。一流は複雑なものをビックリする程単純に作ります。それが設計の極意であり、重要なポイントです。
クラスライブラリのデザインの本質はモジュール化ですから、少なくとも構造化設計・構造化プログラミングの技法に習熟している必要があります。

コンポーネントデザイナーにとって、構造化設計は小中学校の科目同様、義務教育です。それも頭では身につきませんから、構造図もDFD(Data Flow Diagram)も死ぬほど実践し、その上でオブジェクト指向技術が花開くのです。小中学校の勉強を知らなくて、いきなり大学に行っても上手くいかないの と同じです。
それをまとめたのが、下記のコンポーネントデザイナーとコンポーネントアセンブラという新しいシステム作りの枠組みです。
コンポーネントデザイナーとは、SEとプログラマの役割を1人にカプセル化した人材です。カプセルを作るためには、人材もカプセル化が必要というわけです。


・クラスライブラリに求められる条件とは?
皆に容易に使えるツールか?
平易さ、部品の少なさ、オブジェクトの知識の不要など
グラムの変更などに耐えられるか?
変更に対して無防備ではないか?
作ることばかりに意識が向いてないか?
継承やメッセージパッシングの機構が複雑すぎて、難解で保守の難しいツールになっていないか?
再利用性が高いか?
特定の機能のみを満足して、汎用性を失っていないか?
部品の粒度は適正か?(部品の数は適正か?)
何でもできるのは、何にもできないのと同じ。細かすぎて開発者の負担になっていないか?
高生産性と高保守性の2つの条件を同時に満たせるか?
生産性追求のために保守性が犠牲になっていないか?
保守性向上のために生産性が犠牲になっていないか?


・オブジェクト指向とデザインパターン
オブジェクト指向は、一種宗教に似たところがあります。例えば、キリスト教を考えると、米国で信仰されているキリスト教、中国のキリスト教、日本のキリスト教などというように、民族が違っても共通の宗教が存在します。
これはあたかも、C++のオブジェクト指向、Delphiのオブジェクト指向、Smalltalkのオブジェクト指向になぞらえることができます。
異なった言語間でひとつのフレームワークが動くというのは、これまでのソフトウェア言語になかった画期的な概念です。ですから、このフレームワークを使えば、いろいろな言語の間に共通の(設計的に)部品を作成することが可能になるわけです。
ところが困ったことに、この宗教だけでは仕様が発散してしまって、うまく行かないところが出てきました。これでもまだ大雑把すぎるのです。システムとしてもっと高次にインテグレートするためには、そのオブジェクト指向という宗教に、道徳という枠組みが必要になってきたのです。それが、デザインパターンです。これは、クラスライブラリの標準化技法と考えていいと思います。

COBOLは事務処理に向いた言語といわれますが、そのままではやはり発散してしまって、メンテナンスできなくなります。ですから、昔のSEは一生懸命標準化を考えました。オブジェクト指向でデザインパターンを考えるということは、COBOLの世界でいえばスケルトン作りのようなものです。これによって、設計の発散を防ぎます。ここでは、弊社のGUIクラスライブラリのデザインパターンである「間接継承」のデザインパターンを使って、クラスライブラリ の標準設計パターンをどう考えるかを考えたいと思います。間接継承とは本当の継承ではなく、一種のリレーションのモデルです(特許取得済み)。GUIのコ ンポーネントの場合、追加変更に強くて(部品が独立していて)、なおかつ全体として連動する(例えば、最終的にひとつのSQL文が生成される)という、矛盾した要件があって、その問題を解決するために設計されたデザインパターンです。
連動させたいクラスの上に共通の親クラスを持って、その親クラスのパブリック変数やインスタンス変数の値を共有して、その子クラスが連動するしくみです。
このデザインパターンのよいところは、クラスを追加しても縦に増えずに横に増えていくところです。クラスライブラリ全体が、フラットな構造をキープしたまま発展させることが可能なモデルとなっています。
もちろんクラス同士は親クラスからの間接的な関係なので、お互いの追加・変更・削除は全く影響ありません。

最近ではAOP(Aspect Oriented Program:アスペクト指向プログラム)という概念が言われ始めていて、これは、オブジェクト指向と少し違う方法で、ソフトウェアの複雑さの低減や再利用性を向上させるための仕組みであります。

オブジェクト指向が継承により、プログラムコードの重複を回避するのに対し、アスペクト指向では、「アスペクト」によりプログラムコードの重複を省きます。

このアスペクトを行うためのフレームワークはIoC(Inversion of Control:制御の反転)コンテナと呼ばれます。
IoC コンテナを用いると、コンポーネントの依存性を排除することによって、個々のコンポーネントの独立性が高まり、単独でテストを行うことが少しは容易になり ます。また、アプリケーションを超えたコンポーネントの再利用を促進できます。従来のフレームワークは、再利用の対象がフレームワークそのものであったの に対して、コンポーネント指向の開発では、再利用の対象がコンポーネントです。そのため、IoC はコンポーネント指向開発の一つの実現例となるでしょう。
最近は、マーチン・ファウラー氏の呼びかけで、IoCよりDI(Dependency Injection: 依存性の挿入)という言葉を用いることが多くなってきているようです。

IoCとAOP自体は直接は関係のないものですが、AOPを実現するための仕組みの一つとしてIoCが用いられます。IoCとAOPは相性がよいわけです。


実は、ECObjectsの間接継承のしくみはDIコンテナの一種なのです。
Java開発を変える最新の設計思想であり、最先端のフレームワークだったのです。


(※参考:宮本信二氏HP)