フレームワークをアジャイルに作る方法
フレームワークもアジャイルに作ればいいじゃない、という話を書いてみようと思う。うまく書けるか分からないけれど。
僕が思うに、アジャイル的価値観が台頭してくるにつれて、もちろんそれはいいことだけれど、代わりにどうもフレームワーク開発とかライブラリ開発はガチガチのアーキテクチャ側のものとして敬遠されつつあるような気がしている。アジャイルとフレームワーク開発は背反すると思われているというか。でも、現在ヒスイというCADのフレームワークを開発している立場としては、アジャイルの価値観はフレームワークにも十分有効だ、と確信している。
話は変わるけれど、先日、平鍋さんの記事「42歳の抱負。(現在のソフトウェア開発における3つの個人的課題):An Agile Way:オルタナティブ・ブログ」を読んで、ちょっと胸が熱くなった。「業界の課題」みたいなエラそうな批判記事ではなくて、「個人的課題」と題されているところが素晴らしいと思う。平鍋さんがスゴイのは、単なる評論家ではなくて必ず「この課題に対して自分はどう行動するか」という一人称の視点で語ることだ。見習わなくては、と身が引き締まる思いがした。
さて、その記事に下記の記述がある。
再利用性、という価値観と、変更容易性という価値観が独立し、これら2つの価値観は別個に発展する。オブジェクト指向をはじめとする設計手法は、再利用性という方向では組織・流通・資産化を含んだプロダクトライン、変更容易性という方向ではリファクタリング、テスト駆動、アジャイル、というそれぞれのプロセスを伴った方向に分化する。
42歳の抱負。(現在のソフトウェア開発における3つの個人的課題):An Agile Way:オルタナティブ・ブログ
オブジェクト指向がセンセーションを巻き起こした頃、盛んに「再利用性」という言葉が使われたことが懐かしい。継承もポリモーフィズムもカプセル化も、みんな「再利用性」のためにある、という文脈で語られることが多かった。
しかし、昨今ではあまり再利用性という言葉を耳にしなくなった。当初の理想ほど、「ソフトウェアの部品化と再利用」はうまく機能しなかったからだ。逆に、YAGNI(You aren't gonna need it)などの原則が叫ばれるようになり、ソフトウェアの部品化の努力は無駄なコストとして忌み嫌われるようになってしまった。代わりに、オブジェクト指向の効用は「変更容易性」「テスト容易性」という価値観から語られるようになった。
フレームワーク厨な僕としては、この事態はちょいと悲しい。フレームワークを開発することは、僕にとってはとても楽しいことだし、楽しいことには必ず価値があると思いたい。そして、事実として僕が開発しているヒスイはうまく機能してきている。ウチのオフィスでの仕事はヒスイを利用した受託案件一色に染まりつつあるし、他者にはないフレームワークを自社開発したことが強みになっていると思う。
では何故、「ソフトウェアの部品化と再利用は難しい」と言われるようになってしまったのか。僕の根拠のない予想だけど、再利用とか部品化と聞いて、Javaの標準ライブラリとか、C++ の STL とか、Microsoft の MFC とか .NET Framework をイメージしたからじゃないかな。
これは断言してもいいと思うのだけれど、Microsoft のやり方は殆どの会社の参考にはならない。.NET Framework はフレームワーク開発の参考にならないのだ。理由は次の二つ。
- 会社の規模が違いすぎる。Microsoftの規模の会社と同様のやり方なんて出来るわけがない。
- ドメインが違いすぎる。GUI部品クラスやコレクションクラス、スレッドクラスなどと同様の進め方では、ある特定の業界、特定のドメイン向けのソフトウェア部品は開発できない。
もっと具体的に言うと、次の順序で開発を進めようというのは難しいんじゃないか、ということ。既成のフレームワークのイメージで考えると、暗黙のうちに次の順序で開発を進めなくてはダメだと思い込んでしまいがちだ。
- まずフレームワークを作る
- 次にアプリケーションを開発する
ところがこれは、かなり難しい。アプリケーション開発に先立って必要なフレームワークを予め予見するのは非常に難しいのだ。まさにこれがウォーターフォールモデルが上手く機能しない理由であり、アジャイル開発が注目される理由であり、YAGNIの原則が生まれた理由でもある。
それでも、Microsoftのような巨大な企業であれば、事前に必要な機能を全部分析して、優秀なアーキテクトたちが寄ってたかって設計して、完璧なフレームワークを仕上げてしまうことが出来るのかもしれない。でも、普通はそんな余裕はないし、そんなことをしたら部品化と再利用の効果よりもフレームワークの開発コストが上回ってしまう。少なくとも僕には無理だ。
しかも、ある特定ドメインむけのフレームワークとなると更に難しくなる。特定ドメインに依存しないようなプリミティブなクラス、例えばListやStackみたいな単純なコレクションクラスの設計ならば、ある程度の経験あるプログラマなら誰でも要件を洗い出せる。ところが、あるドメインに特化したフレームワークとなるとそうは行かないよね。
そんなわけで、現時点では僕はこう思っている。
- フレームワークは、アプリケーションと同時に作るべきだ。
- フレームワーク開発者(開発チーム)とアプリケーション開発者(開発チーム)は同じであるべきだ。
- フレームワークの仕様は必要があれば恐れることなく変更せよ。
ソフトウェア開発において最大のムダは、不要な機能を作ってしまうことだ。これはフレームワークにもいえる。しかし、まずフレームワークを用意して次にアプリケーションを開発する、という順序だとこの無駄が発生しやすい。前工程からのプッシュで作ってはいけないのだ。
そうではなくて、後工程からのプルに駆動される形でフレームワークを開発するべきだと思う。フレームワーク開発は、アプリケーション開発のニーズに駆動されるべきなのだ。そして、フレームワークに追加された機能はすぐにアプリケーションで利用する。フレームワーク開発とアプリケーション開発を同時に同じ人物(同じチーム)が行えば、この2つはシームレスに接続する。
もちろん、フレームワークの効用は再利用にあるわけだから、次の新しいプロジェクトでもそのフレームワークを利用することになる。そして、利用すると同時に開発もする。アプリケーションとフレームワークは、常に同時に育っていくのだと思う。
顧客の要求がアプリケーション開発を駆動し、アプリケーションの要求がフレームワーク開発を駆動するのだ。
ただし、このやり方だと事前に要件を分析して設計を練り上げているわけではないから、フレームワークを仕様変更しなくてはならない場面が出てきてしまう。僕はそれでいいと思っている。恐れることなく、どんどん仕様変更してフレームワークを洗練させればいい。
フレームワークの仕様変更は厄介だけれど、アジャイルな価値観で考えれば Embrace Change しなくてはならないだろう。.NET Framework の List クラスの仕様がある日突然変わったとしたら世界中から非難の声が上がるだろうけど、社内だけで細々と使っているフレームワークならばオフィス内の数人がちょっと呻き声を上げる程度で済むはずだ。フレームワークの利用者が少ないうちは、恐れることなくガンガン仕様変更して美しいフレームワークへと洗練していく方が良い。仕様をFIXするのはもっとユーザーが増えてから考えればいいことだし、その頃には徐々に仕様も枯れてきているはずだから問題ない。
まとめると、言いたかったことは次の2つ。