「動く」ことを認識しながらソフトウェアを書く実行可能な知識とソフトウェア(7)

……動きの入っていないモデルはいくら精密に美しく書かれていても、「実行可能知識」であるソフトウェアとしては、「仏作って魂入れず」なのである(本文より)

» 2004年09月23日 12時00分 公開
[山田正樹,メタボリックス]

 ソフトウェアという「知識 (表現)」がほかの知識と大きく変わっているところは、「柔らか」く「移ろいやすい」ということ、そして「動く」ということだ。典型的な知識(表現)である書物は、いったん印刷されたらほとんど変わることはないし、「実行」されることもない。もっとビジュアル な知識(表現)、例えば、 CGアニメーションは確かに「動く」けれど、もちろんここでいう「動く」とは意味が違う。外界の何かに反応してあるいは自律的に内容が変化して、それがそれ自身の表現や外界に反映される、というのがここでいう「動く」ということだ。

 それにもかかわらず、多くの人はソフトウェアを作る過程であまり「動く」ということに注意を払わない。確かに最近UMLのようなものを使ったモデリングをする機会が多くなったはずだが、ユースケース図やクラス図しか描かないという人も多いのではないだろうか? いやいや、クラス図には属性だけじゃなくて、ちゃんと操作も書くよ、というかもしれないけれど、あれは実は単に「属性名」「操作名」でしかない。属性は名前があればまぁよい、どうせ値を入れる単なる「場所」なんだからまっとうな名前さえ付いていれば許そう。でも操作名は「私が理解できる言葉はこれこれです」と宣言している辞書にすぎない。何の動きも表していないのである。

 動きの入っていないモデルはいくら精密に美しく書かれていても、「実行可能知識」であるソフトウェアとしては、「仏作って魂入れず」なのである。

 特にビジネス・アプリケーションを開発している現場ではいくらオブジェクトという言葉がはやっていたとしても、実際にはデータ中心であることが多い。まずデータをきっちり定義して、次にそれがどう動くか考えよう、というわけだ。だから動き、振る舞いを実際に考えるのは最後の最後、実際のプログラミング言語を使ったコーディングのときになってしまう(注1)。そうすると動きを変えようとしたときに思ったようにいかない(保守)とか、そもそも思ったように動くとはどういうことかよく分からない(テスト)とかいう事態に陥るのも当然の話でしょ?

注1

 例えばフローチャートを使ったとしてもそれはプログラムのステップを書くのと大して違わない。「動く」ということの本質はそこには表れていないから。同様に仕様書に自然言語でだらだらと仕様が書いてあったとしても、それは実際には「動き」ではない。



 「じゃあ、そうじゃないやり方なんてあるんですか? 車だってまず車を作ってから動かすでしょ? 動かしながら車を作るなんてあり得ない!(注2)」。いえいえ、それがあるんですよ。それがソフトウェアというもんなんですから。ソフトウェアの場合には、ソフトウェアを作るのも(人間以外は)すべてソフトウェアなわけですから。

注2

 実は車もソフトウェアとそんなに違うわけではない。モノとしての車を作るとき(製造)には確かに車という物理存在がなければ動かしようもないけど、設計するときには逆で動くようにするためにすべての部品を考えるのである。そのために車は多分設計者の頭の中では「動いて」いる。



 構造を考えるのと同時に動かしたい。それが開発の「生産性」を最も高める手段の 1つだし、ソフトウェアにはそれができるはずだ。その方法はいくつかある。

 1つは要求から直接実装コードを生み出し、構造を書くと同時に動きも書き、同時にテストの形で実際に動かす、 XP的な方法だ。この場合は構造を書くのと動きを書くのと動かすのが同時というよりは、むしろまず動かして、それにドライブされて動きを書き、それにドライブされて構造が決まるといった方がいい。徹底したボトムアップの方法であるが、動きの記述は通常の手続き型プログラミング言語程度の抽象度しかないので、とにかくしょっちゅうリファクタリングしていないと動きの本質が見えなくなってしまうのが難点だ。

 もっと動きの本質を表すことはできないか? これにもいくつかの方法がある。 1つは動きをある特定の入力(あるいは環境の変化)があったときにある特定の出力をするもの、と決めることだ。代数的仕様記述とか、論理プログラミングとか、ルール・ベースとか、制約指向とかはこのグループに入る。ある意味で動きを静的なものとしてとらえることによって抽象化している。で、動きそのものの動的な部分はどこにいったかというと、そのインタプリタに押し込められている。

 これは特別に研究的な話というわけではなく、実際のプロジェクトでもよく使われる方法だ。ある特定の領域の背後に共通する動きがあるんだとしたら、その動きそのものは(小さな)インタプリタとして作り、ルールをデータとして入力する。最初に作るのは少し大変だけど、いったん作ってしまえばバリエーションや拡張をすべてルールとして静的に記述して実行時に食わせることができるので柔軟性や生産性、保守性が非常に高くなる。例えば UNIXの開発ツールであるmakeってそういうものでしょ。ビジネス・ルールをいちいちコードとして記述するのではなく、ルールとそのインタプリタとして書くやり方もよく行われる。

 もう 1 つは動きをオートマトンとして考えるやり方だ。オートマトンとは「自分で動くもの」だからまさに動きそのものを抽象化したモデルで、「ある事象が起きたらあることをする」ものを組み合わせた機械だ。なじみの深いものとしては例えば UMLの状態図を考えればよい。前の例に比べるとこっちはインタプリタ(動き)そのものを抽象的に考えようという方向だ。

 普通のプログラミングだけでもヒーヒーいっているのに、さらにこんなものを考えるなんて、何がうれしいんだろう? 状態図は直接動かせる。しかも通常のプログラミング言語で動きを記述するのに比べて、動きの本質以外のことに気を使う必要がない。つまり、生産性が極めて高い。しかも本質だけが書いてあるから変更が容易だ。つまり、拡張性や保守性も高い。そしてあらゆることを考えた後にようやく動かせるようになるの

ではなく、考え始めたその時点から、つまり分析や基本設計の段階から実際に動かせる。

 まだある。それはこういう高尚で小難しい(!?)ことは考えたくない人向きかもしれない。どうせ(手続き型)プログラミング言語を使うならば、もっとまともなプログラミング言語を使うことだ。実際、プログラミング言語の背後にあるモデルもある種のオートマトンだし、プログラミング言語もある種のインタプリタで実行されているはずだ。にもかかわらず、(大方の)プログラミング言語がこんなにややこしく、間違いやすく、本質が見えにくいのはなぜだろうか。 GroovyやRuby、Pythonなどいわゆる「スクリプト」系の言語、あるいはSchemeやSmalltalk 、ML系統の「懐かしの」言語が少しずつではあってもなし崩し的に使われるようになってきているのには、多分それなりの理由があるはずだ。

 商用ソフトウェア開発に当たって慎重になるあまり、「動き」をどう表現するか、どう実現するかについてあまりに保守的な姿勢がまかり通ってきたように思えるけれど、ソフトウェアは「動いてなんぼ」なんだから、アーキテクトはもう少し頑張ってもいいかもしれない。

 さて、この連載ではこれまで、ソフトウェア開発を実行可能な知識の変換過程と見る立場から、「知っていることを(第1回「システムに適した知識の表現方法を探る」正しく、(第2回「知識とソフトウェアのギャップ、それをどう埋めるのか?」)分ける(第3回「ドメイン・エンジニアリング温故知新」)ことによって分かり(第4回「モデリングの神さまが降りてくる瞬間」)、分けたものを変換して(第6回「『要求』から『コード』に至る長く険しい道」)、つなぐ(第5回「フレームワークの本当の意味」)ことによって動かす(今回)」というアーキテクトの仕事を追いかけてきた。次回は中入りの話題でいったん“休憩”し、あらためて後半戦へ入ろうと考えている。

著者プロフィール

山田正樹

(株)ソフトウェア・リサーチ・アソシエイツ 、(株)ソニーコンピュータサイエンス研究所を経て、1995年(有)メタボリックス設立。代表取締役。アーキテクチャ、モデリング、マネージメント、コラボレーションなどを含む広い意味でのソフトウェア・プロセス・エンジニアリングが専門。ソフトウェア・ツール開発、メンタリング、コンサルティングなどを行っている。


Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ