変幻する実行可能知識 05「つなぐといふこと」ソフトウェアを作るということは, ものごとを「分ける」= 「分かる」ということなのであった. 分け方にはいろいろあるけれど, 分けたものを分けたままにしておいても生命を持ったソフトウェアとして動き出すことはない. 分けたものはなんとかしてつながなくてはならないのである. 分けることを分析 (analysis) といい, つなぐことを総合 (synthesis) ということもある. ソフトウェアを作るときの分けるやり方には例えばモジュール, オブジェクト, ドメイン, アスペクトなどさまざまな方法やレベルがあった. その裏には必ず分けたものをつなげるやり方が隠されている. 分けるやり方に較べてつなげるやり方をあまり意識することはないかも知れないけれど, 実はつなげる方が格段に難しい. つなげ方を間違うとフランケンシュタインのようなものができてしまうかも知れないからだ. だからつなげる方の細かいことはできるだけ人間があれこれ考えなくてもできるように工夫されてはいる. モジュールとモジュールをつなぐにはインタフェースを使う. インタフェースを通して別のモジュールを呼び出す. 呼び出す仕組みはたいていリンカとかローダと呼ばれるツールが面倒を見てくれる. 呼び出し先がコンパイル時に静的に決まる場合は比較的簡単だけれど, Javaのようにもしかしたらネットワーク上の別の場所から探してこなければならない場合には「本当につないでもいいのかどうか」をセキュリティの面からいちいちチェックしなければならない. オブジェクトとオブジェクトをつなぐのはメッセージ交換だ. モジュールのつなぎ方よりは少しだけ柔軟性が高い. モジュールをつなぐというのは相手を決めるということだったけれど, オブジェクトの場合にはそれはあまり重要ではない. 行き先はメッセージに聞いてくれ, みたいなところがある. 実際, ローカルなオブジェクトにメッセージを送ったつもりだったのにそれはプロキシ (代理人) で, 最終的にはリモートのオブジェクトに送られてしまうというのがオブジェクト指向のリモート・メッセージングの基本的な仕組みだ. さらにモジュールの場合にはインタフェースを通してモジュールのどのサービスを呼び出すかも最初からほとんど決めてしまうのだけれど, オブジェクトの場合にはそれを決めるのもメッセージを送った方ではなく, メッセージを受け取った方になる. 例えば「図形」オブジェクトに「描け」と言っても「丸」オブジェクトならば丸を描き, 「三角」オブジェクトならば三角を描く. いわゆるポリモルフィズムはメッセージを受け取った側の主体性から生まれる. オブジェクト指向のポリモルフィズムなどは一部の人からは「何が起こるか分からない」という理由でひどく嫌われることがある. 我々ソフトウェア・アーキテクトにとって「柔軟につなぐ」ということは, いいことなんだろうか? 悪いことなんだろうか? もちろんそれはどんな状況かによる. とても小さな世界で登場人物も起こる出来事も初めからみんなはっきりと分かっていて, それ以上変化することがないのならば柔軟性なんてものは出る幕がないだろう. でもそうでなければ, つまり我々の作るソフトウェアが「複雑な世界」ならばソフトウェア・アーキテクトやプログラマがすべてを取り仕切ろうと考えるのは諦めた方がいいのかも知れない. オブジェクトのメッセージ交換の考え方はすべてを人間が制御するのではなく, 「つながれ方」の仕組みをオブジェクトの方に入れておいて「勝手につながれ」という考え方だ. もっとも数億年をかけて進化してきた生物と違って人間が後知恵で作ったものだからつながれ方の仕組みを考えるのは大変なんだけれど, どうせ後で大きな苦労するのならば先に少しだけ苦労しておけ, というわけだ.
ここまでは一つ一つのモジュールなりオブジェクトの間のつなぎ方を考えてきたけれど, つなぐためにはそのつなぎ方の「土台」みたいなものがあるともっと便利だ. 例えばこんなつなぎ方もあるけれど, こんな真似は誰にでもはできないし, デバッグも多分半端じゃなく大変だろう. だからこういう枠を決めてしまえばまぁ小学生でも多分大丈夫じゃないか. 我々はこれを「フレームワーク」と呼ぶ. EJBなんてのもフレームワークの一例と考えていいだろう. フレームワークが与えられるともうつなぎ方は大方決まってしまう. どうやってつなごうと苦労して考えるまでもなく, 「この線とこの線だけは用意しておいてね, 後は適当な場所に置いておいてくれれば, 適当につながるから」ってなもんである. フレームワークがあればつなぎ方は大体決まってくるから楽といえば楽なんであるが, ある意味ですべてがフレームワーク次第ということになってしまう. やたらに長々しい呪文を唱えないとつないでくれないフレームワークとか, フレームワークがちょっとでも想定していないことをやろうとするとめちゃくちゃ大変なことになるフレームワークとか, フレームワークと言いながら結局自分でほとんどつなぎ直す羽目に陥るフレームワークとかいっぱいある (あれとかあれとか...ね. もちろん素晴らしいフレームワークもいくつかある). フレームワークを作るのは大変なんである. フレームワークというのはつまり, つなぎ方の集大成といっていい. 「こういうものを作るためにはこういう部品をこうやってつなぐとうまくいく」という知識を寄せ集めて, それをみんなが使えるようなソフトウェアにしたものがフレームワークだ. 「こういうものを作るためにはこういう部品をこうやってつなぐとうまくいく」という質のいい知識がいっぱい集まっていないうちに, フレームワークを作り始めるとろくなフレームワークにはならない. 「こういうものを作るためにはこういう部品をこうやってつなぐとうまくいく」という質のいい知識がいっぱい集まったものを「パターン・ランゲージ」と呼ぶことは皆さんご存じだろう. いわゆるパターンは自然言語であるパターン言語で記述されたものなのでそのまま「実行可能な知識」ではないけれど, それを「実行可能な知識」にしたものがフレームワークである. フレームワークには大きな資産価値がある. もしあなたのチームが似たようなものを3回目に作ることになったのなら, 最初の1ヶ月をかけて今までの成果をフレームワークにまとめる価値があるかも知れない. 今まで話してきたのはオブジェクトならオブジェクトという多くの同じようなものをつなぐ方法だった. でもソフトウェアを作るときには, まったく異なるものをつなげる必要も出てくる. 前に「ドメインに分ける」という話が出てきたけれども (第3回), ドメインというのは「領土」や「分野」を表しているくらいで一つ一つが大変に異なっている. 例えばお風呂の給湯システムを作るとしたら,
なんてのがあるわけだ. センサやアクチュエータのドメインは割り込みやイベントが飛び交い, ポートにバイトを読み書きする物理レベルの世界で, その世界では「快適な湯温」なんて概念は存在しない. 一方お風呂のドメインでは湯温を快適に保つとか, 熱すぎて火傷しないようにするのが重要で, どのアドレスにどの値を書きこむと何が起きるかなんてことは知るよしもない. それぞれのドメインが自分の仕事を精一杯こなしているのだが, やっぱりどこかでは他のドメインの助けが必要になる. この「異なる世界や言葉」をつなぐ通訳の役割をするのが, 「ブリッジ」だ. ブリッジは自分で何かをするわけではないけれど, あるドメインからの要求を別のドメインに理解可能な言葉に訳して伝える. つまりブリッジは単に何かを伝えるだけではなく, 知識から知識への変換を行うことによってつなぐ仕掛けということになる. そして我々はソフトウェアを作るとは知識変換過程であると主張しているのだから, ブリッジに相当するものはとても重要な役割を果たしていることになる. その話はまた別の機会に. 人生いろいろ, つなぎ方いろいろ (今回はオチはない...) |